use of jp.ossc.nimbus.service.context.SharedContextSendException in project nimbus by nimbus-org.
the class SharedQueueService method onLockFirst.
protected Message onLockFirst(SharedContextEvent event, final Object sourceId, final int sequence, final String responseSubject, final String responseKey) {
if (isMain(sourceId)) {
final Object[] params = (Object[]) event.value;
final long threadId = ((Long) params[0]).longValue();
long timeout = ((Long) params[1]).longValue();
Object[] keys = null;
if (context.size() != 0) {
synchronized (context) {
if (context.size() != 0) {
keys = context.keySet().toArray();
}
}
}
if (keys == null || keys.length == 0) {
return createResponseMessage(responseSubject, responseKey, null);
}
for (int i = 0; i < keys.length; i++) {
final Object key = keys[i];
if (!containsKey(key)) {
continue;
}
Lock lock = null;
synchronized (keyLockMap) {
lock = (Lock) keyLockMap.get(key);
if (lock == null) {
lock = new Lock(key);
keyLockMap.put(key, lock);
}
}
final long start = System.currentTimeMillis();
if (lock.acquireForReply(sourceId, threadId, true, true, timeout, sourceId, sequence, responseSubject, responseKey)) {
if (!containsKey(key)) {
lock.release(sourceId, false);
continue;
}
final boolean isNoTimeout = timeout <= 0;
timeout = isNoTimeout ? timeout : (timeout - (System.currentTimeMillis() - start));
if (!isNoTimeout && timeout <= 0) {
lock.release(sourceId, false);
return createResponseMessage(responseSubject, responseKey, null);
} else {
try {
Message message = serverConnection.createMessage(subject, key.toString());
message.setSubject(clientSubject, key.toString());
final Set receiveClients = serverConnection.getReceiveClientIds(message);
receiveClients.remove(sourceId);
if (receiveClients.size() != 0) {
message.setDestinationIds(receiveClients);
message.setObject(new SharedContextEvent(SharedContextEvent.EVENT_GOT_LOCK, key, new Object[] { sourceId, new Long(threadId), new Long(timeout) }));
final Lock lockedLock = lock;
serverConnection.request(message, isClient ? clientSubject : subject, key == null ? null : key.toString(), 0, timeout, new RequestServerConnection.ResponseCallBack() {
public void onResponse(Object fromId, Message response, boolean isLast) {
if (receiveClients.size() == 0) {
return;
}
try {
if (response == null) {
unlock(key);
serverConnection.response(sourceId, sequence, createResponseMessage(responseSubject, responseKey, null));
receiveClients.clear();
return;
}
receiveClients.remove(fromId);
Object ret = response.getObject();
response.recycle();
if (ret == null || ret instanceof Throwable || !((Boolean) ret).booleanValue()) {
unlock(key);
serverConnection.response(sourceId, sequence, createResponseMessage(responseSubject, responseKey, null));
receiveClients.clear();
} else if (isLast) {
serverConnection.response(sourceId, sequence, createResponseMessage(responseSubject, responseKey, key));
}
} catch (Throwable th) {
try {
unlock(key);
} catch (SharedContextSendException e) {
getLogger().write("SCS__00007", new Object[] { isClient ? clientSubject : subject, key }, e);
}
try {
serverConnection.response(sourceId, sequence, createResponseMessage(responseSubject, responseKey, th));
} catch (MessageSendException e) {
getLogger().write("SCS__00006", new Object[] { isClient ? clientSubject : subject, key }, e);
}
}
}
});
return null;
} else {
return createResponseMessage(responseSubject, responseKey, key);
}
} catch (Throwable th) {
try {
unlock(key);
} catch (SharedContextSendException e) {
getLogger().write("SCS__00007", new Object[] { isClient ? clientSubject : subject, key }, e);
}
return createResponseMessage(responseSubject, responseKey, th);
}
}
}
}
return createResponseMessage(responseSubject, responseKey, null);
}
return null;
}
use of jp.ossc.nimbus.service.context.SharedContextSendException in project nimbus by nimbus-org.
the class SharedQueueService method lockFirst.
protected Object lockFirst(long timeout) throws SharedContextSendException, SharedContextTimeoutException {
if (isMain()) {
List keys = null;
if (context.size() != 0) {
synchronized (context) {
if (context.size() != 0) {
Iterator itr = context.keySet().iterator();
for (int i = 0; i < seekDepth && itr.hasNext(); i++) {
if (keys == null) {
keys = new ArrayList();
}
keys.add(itr.next());
}
}
}
}
if (keys == null || keys.size() == 0) {
return null;
}
for (int i = 0; i < keys.size(); i++) {
Object key = keys.get(i);
try {
if (lock(key, true, true, timeout)) {
return key;
}
} catch (SharedContextTimeoutException e) {
continue;
}
}
return null;
} else {
Object lockedKey = null;
final long start = System.currentTimeMillis();
try {
String key = getId().toString() + Thread.currentThread().getId();
Message message = serverConnection.createMessage(subject, key);
Set receiveClients = serverConnection.getReceiveClientIds(message);
if (receiveClients.size() != 0) {
message.setObject(new SharedQueueEvent(SharedQueueEvent.EVENT_LOCK_FIRST, null, new Object[] { new Long(Thread.currentThread().getId()), new Long(timeout) }));
Message[] responses = serverConnection.request(message, isClient ? clientSubject : subject, key, 1, timeout);
Object ret = responses[0].getObject();
responses[0].recycle();
if (ret instanceof Throwable) {
throw new SharedContextSendException((Throwable) ret);
} else {
lockedKey = ret;
}
} else {
throw new NoConnectServerException("Main server is not found.");
}
} catch (MessageException e) {
throw new SharedContextSendException(e);
} catch (MessageSendException e) {
throw new SharedContextSendException(e);
} catch (RequestTimeoutException e) {
final boolean isNoTimeout = timeout <= 0;
timeout = isNoTimeout ? timeout : timeout - (System.currentTimeMillis() - start);
if (!isNoTimeout && timeout <= 0) {
throw new SharedContextTimeoutException("timeout=" + timeout + ", processTime=" + (System.currentTimeMillis() - start), e);
} else {
return lockFirst(timeout);
}
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
}
if (lockedKey != null) {
Lock lock = null;
synchronized (keyLockMap) {
lock = (Lock) keyLockMap.get(lockedKey);
if (lock == null) {
lock = new Lock(lockedKey);
keyLockMap.put(lockedKey, lock);
}
}
final boolean isNoTimeout = timeout <= 0;
timeout = isNoTimeout ? timeout : timeout - (System.currentTimeMillis() - start);
if (!isNoTimeout && timeout <= 0) {
unlock(lockedKey);
throw new SharedContextTimeoutException("timeout=" + timeout + ", processTime=" + (System.currentTimeMillis() - start));
} else if (!lock.acquire(getId(), true, timeout)) {
unlock(lockedKey);
return null;
}
}
return lockedKey;
}
}
Aggregations