use of com.orientechnologies.orient.core.sql.query.OLiveQuery in project orientdb by orientechnologies.
the class OStorageRemote method command.
/**
* Execute the command remotely and get the results back.
*/
public Object command(final OCommandRequestText iCommand) {
if (!(iCommand instanceof OSerializableStream))
throw new OCommandExecutionException("Cannot serialize the command to be executed to the server side.");
final boolean live = iCommand instanceof OLiveQuery;
final ODatabaseDocument database = ODatabaseRecordThreadLocal.INSTANCE.get();
return networkOperation(new OStorageRemoteOperation<Object>() {
@Override
public Object execute(final OChannelBinaryAsynchClient network, OStorageRemoteSession session) throws IOException {
Object result = null;
session.commandExecuting = true;
try {
final boolean asynch = iCommand instanceof OCommandRequestAsynch && ((OCommandRequestAsynch) iCommand).isAsynchronous();
try {
beginRequest(network, OChannelBinaryProtocol.REQUEST_COMMAND, session);
if (live) {
network.writeByte((byte) 'l');
} else {
// ASYNC / SYNC
network.writeByte((byte) (asynch ? 'a' : 's'));
}
network.writeBytes(OStreamSerializerAnyStreamable.INSTANCE.toStream(iCommand));
} finally {
endRequest(network);
}
try {
beginResponse(network, session);
// Collection of prefetched temporary record (nested projection record), to refer for avoid garbage collection.
List<ORecord> temporaryResults = new ArrayList<ORecord>();
boolean addNextRecord = true;
if (asynch) {
byte status;
// ASYNCH: READ ONE RECORD AT TIME
while ((status = network.readByte()) > 0) {
final ORecord record = (ORecord) OChannelBinaryProtocol.readIdentifiable(network);
if (record == null)
continue;
switch(status) {
case 1:
// PUT AS PART OF THE RESULT SET. INVOKE THE LISTENER
if (addNextRecord) {
addNextRecord = iCommand.getResultListener().result(record);
database.getLocalCache().updateRecord(record);
}
break;
case 2:
if (record.getIdentity().getClusterId() == -2)
temporaryResults.add(record);
// PUT IN THE CLIENT LOCAL CACHE
database.getLocalCache().updateRecord(record);
}
}
} else {
result = readSynchResult(network, database, temporaryResults);
if (live) {
final ODocument doc = ((List<ODocument>) result).get(0);
final Integer token = doc.field("token");
final Boolean unsubscribe = doc.field("unsubscribe");
if (token != null) {
if (Boolean.TRUE.equals(unsubscribe)) {
if (OStorageRemote.this.asynchEventListener != null)
OStorageRemote.this.asynchEventListener.unregisterLiveListener(token);
} else {
final OLiveResultListener listener = (OLiveResultListener) iCommand.getResultListener();
ODatabaseDocumentInternal current = ODatabaseRecordThreadLocal.INSTANCE.get();
final ODatabaseDocument dbCopy = current.copy();
ORemoteConnectionPool pool = OStorageRemote.this.connectionManager.getPool(network.getServerURL());
OStorageRemote.this.asynchEventListener.registerLiveListener(pool, token, new OLiveResultListener() {
@Override
public void onUnsubscribe(int iLiveToken) {
listener.onUnsubscribe(iLiveToken);
dbCopy.close();
}
@Override
public void onLiveResult(int iLiveToken, ORecordOperation iOp) throws OException {
dbCopy.activateOnCurrentThread();
listener.onLiveResult(iLiveToken, iOp);
}
@Override
public void onError(int iLiveToken) {
listener.onError(iLiveToken);
dbCopy.close();
}
});
}
} else {
throw new OStorageException("Cannot execute live query, returned null token");
}
}
}
if (!temporaryResults.isEmpty()) {
if (result instanceof OBasicResultSet<?>) {
((OBasicResultSet<?>) result).setTemporaryRecordCache(temporaryResults);
}
}
return result;
} finally {
endResponse(network);
}
} finally {
session.commandExecuting = false;
if (iCommand.getResultListener() != null && !live)
iCommand.getResultListener().end();
}
}
}, "Error on executing command: " + iCommand);
}
use of com.orientechnologies.orient.core.sql.query.OLiveQuery in project orientdb by orientechnologies.
the class OStreamSerializerAnyStreamable method toStream.
/**
* Serialize the class name size + class name + object content
*/
public byte[] toStream(final Object iObject) throws IOException {
if (iObject == null)
return null;
if (!(iObject instanceof OSerializableStream))
throw new OSerializationException("Cannot serialize the object [" + iObject.getClass() + ":" + iObject + "] since it does not implement the OSerializableStream interface");
OSerializableStream stream = (OSerializableStream) iObject;
// SERIALIZE THE CLASS NAME
final byte[] className;
if (iObject instanceof OLiveQuery<?>)
className = iObject.getClass().getName().getBytes("UTF-8");
else if (iObject instanceof OSQLSynchQuery<?>)
className = QUERY_COMMAND_CLASS_ASBYTES;
else if (iObject instanceof OCommandSQL)
className = SQL_COMMAND_CLASS_ASBYTES;
else if (iObject instanceof OCommandScript)
className = SCRIPT_COMMAND_CLASS_ASBYTES;
else {
if (iObject == null)
className = null;
else
className = iObject.getClass().getName().getBytes("UTF-8");
}
// SERIALIZE THE OBJECT CONTENT
byte[] objectContent = stream.toStream();
byte[] result = new byte[4 + className.length + objectContent.length];
// COPY THE CLASS NAME SIZE + CLASS NAME + OBJECT CONTENT
System.arraycopy(OBinaryProtocol.int2bytes(className.length), 0, result, 0, 4);
System.arraycopy(className, 0, result, 4, className.length);
System.arraycopy(objectContent, 0, result, 4 + className.length, objectContent.length);
return result;
}
use of com.orientechnologies.orient.core.sql.query.OLiveQuery in project orientdb by orientechnologies.
the class OLiveQueryShotdownTest method testShutDown.
@Test
public void testShutDown() throws Exception {
bootServer();
ODatabaseDocument db = new ODatabaseDocumentTx("remote:localhost/" + OLiveQueryShotdownTest.class.getSimpleName());
db.open("admin", "admin");
db.getMetadata().getSchema().createClass("Test");
final CountDownLatch error = new CountDownLatch(1);
try {
db.command(new OLiveQuery("live select from Test", new OLiveResultListener() {
@Override
public void onUnsubscribe(int iLiveToken) {
}
@Override
public void onLiveResult(int iLiveToken, ORecordOperation iOp) throws OException {
}
@Override
public void onError(int iLiveToken) {
error.countDown();
}
})).execute();
shutdownServer();
assertTrue("onError method never called on shutdow", error.await(2, TimeUnit.SECONDS));
} finally {
// db.close();
}
}
Aggregations