use of com.orientechnologies.orient.core.db.record.ORecordOperation in project orientdb by orientechnologies.
the class OLiveQueryHook method addOp.
protected void addOp(ODocument iDocument, byte iType) {
if (Boolean.FALSE.equals(database.getConfiguration().getValue(OGlobalConfiguration.QUERY_LIVE_SUPPORT)))
return;
ODatabaseDocument db = database;
OLiveQueryOps ops = getOpsReference((ODatabaseInternal) db);
if (!ops.queueThread.hasListeners())
return;
if (db.getTransaction() == null || !db.getTransaction().isActive()) {
// TODO synchronize
ORecordOperation op = new ORecordOperation(iDocument.copy(), iType);
ops.queueThread.enqueue(op);
return;
}
ORecordOperation result = new ORecordOperation(iDocument, iType);
synchronized (ops.pendingOps) {
List<ORecordOperation> list = ops.pendingOps.get(db);
if (list == null) {
list = new ArrayList<ORecordOperation>();
ops.pendingOps.put(db, list);
}
list.add(result);
}
}
use of com.orientechnologies.orient.core.db.record.ORecordOperation in project orientdb by orientechnologies.
the class OLiveQueryHook method onAfterTxCommit.
@Override
public void onAfterTxCommit(ODatabase iDatabase) {
if (Boolean.FALSE.equals(database.getConfiguration().getValue(OGlobalConfiguration.QUERY_LIVE_SUPPORT)))
return;
OLiveQueryOps ops = getOpsReference((ODatabaseInternal) iDatabase);
List<ORecordOperation> list;
synchronized (ops.pendingOps) {
list = ops.pendingOps.remove(iDatabase);
}
// TODO sync
if (list != null) {
for (ORecordOperation item : list) {
item.setRecord(item.getRecord().copy());
ops.queueThread.enqueue(item);
}
}
}
use of com.orientechnologies.orient.core.db.record.ORecordOperation 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.db.record.ORecordOperation in project orientdb by orientechnologies.
the class OStorageRemoteAsynchEventListener method onRequest.
public void onRequest(final byte iRequestCode, final Object obj) {
//Using get status to avoid to check the session.
if (storage.getStatus() == STATUS.CLOSED)
return;
if (iRequestCode == OChannelBinaryProtocol.REQUEST_PUSH_DISTRIB_CONFIG) {
storage.updateClusterConfiguration(null, (byte[]) obj);
if (OLogManager.instance().isDebugEnabled()) {
synchronized (storage.getClusterConfiguration()) {
OLogManager.instance().debug(this, "Received new cluster configuration: %s", storage.getClusterConfiguration().toJSON("prettyPrint"));
}
}
} else if (iRequestCode == OChannelBinaryProtocol.REQUEST_PUSH_LIVE_QUERY) {
byte[] bytes = (byte[]) obj;
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
Integer id = null;
try {
byte what = dis.readByte();
if (what == 'r') {
byte op = dis.readByte();
id = dis.readInt();
final ORecord record = Orient.instance().getRecordFactoryManager().newInstance(dis.readByte());
final int version = readVersion(dis);
final ORecordId rid = readRID(dis);
final byte[] content = readBytes(dis);
ORecordInternal.fill(record, rid, version, content, false);
OLiveResultListener listener = liveQueryListeners.get(id);
if (listener != null) {
listener.onLiveResult(id, new ORecordOperation(record, op));
} else {
OLogManager.instance().warn(this, "Receiving invalid LiveQuery token: " + id);
}
} else if (what == 'u') {
id = dis.readInt();
OLiveResultListener listener = liveQueryListeners.get(id);
listener.onUnsubscribe(id);
}
} catch (IOException e) {
if (id != null) {
OLiveResultListener listener = liveQueryListeners.get(id);
if (listener != null) {
listener.onError(id);
}
}
e.printStackTrace();
}
}
byte op;
}
use of com.orientechnologies.orient.core.db.record.ORecordOperation in project orientdb by orientechnologies.
the class OTransactionOptimistic method rollback.
@Override
public void rollback(boolean force, int commitLevelDiff) {
if (txStartCounter < 0)
throw new OStorageException("Invalid value of TX counter");
checkTransaction();
txStartCounter += commitLevelDiff;
status = TXSTATUS.ROLLBACKING;
if (!force && txStartCounter > 0) {
OLogManager.instance().debug(this, "Nested transaction was closed but transaction itself was scheduled for rollback.");
return;
}
if (txStartCounter < 0)
throw new OTransactionException("Transaction was rolled back more times than it was started.");
database.getStorage().callInLock(new Callable<Void>() {
public Void call() throws Exception {
database.getStorage().rollback(OTransactionOptimistic.this);
return null;
}
}, true);
// CLEAR THE CACHE
database.getLocalCache().clear();
// REMOVE ALL THE DIRTY ENTRIES AND UNDO ANY DIRTY DOCUMENT IF POSSIBLE.
for (ORecordOperation v : allEntries.values()) {
final ORecord rec = v.getRecord();
if (rec.isDirty())
if (rec instanceof ODocument && ((ODocument) rec).isTrackingChanges())
((ODocument) rec).undo();
else
rec.unload();
}
close();
status = TXSTATUS.ROLLED_BACK;
}
Aggregations