DatabaseAsyncExecutor Interface

This is the class to manage asynchronous operations. To obtain an instance of DatabaseAsyncExecutor, use the method .async() in Database.

The Asynchronous API schedule the operation to be executed as soon as possible, but by a different thread. ArcadeDB optimizes the usage of asynchronous threads to be equals to the number of cores found in the machine (but it is still configurable). Use Asynchronous API if the response of the operation can be managed in asynchronous way and if you want to avoid developing Multi-Threads application by yourself.

query( language, command, callback, positionalParameters )

Executes a query in asynchronous way, with optional positional parameters. This method returns immediately. This method only executes idempotent statements, namely SELECT and MATCH, that cannot change the database. The execution of any other commands will throw a IllegalArgumentException exception.

Syntax:

void query( String language, String command, AsyncResultsetCallback callback,
            Object... positionalParameters )

Where:

  • language is the language to use

  • command is the command to execute If the language supports prepared statements (SQL does), you can specify parameters by using ? for positional replacement If the language supports prepared statements (SQL does), you can specify parameters by name by using :<arg-name>

  • callback optional, is the callback that will be used for the whole lifecycle of the result set:

    • onStart() executed when the query is parsed and the first result ready

    • onNext() executed foreach result in the result set Return true to continue browsing the result set, otherwise false to interrupt fetching the result set

    • onComplete() executed when the entire result set is browsed, or the onNext() returned false to interrupt the browsing

    • onError() in case of any exception while executing the query

  • positionalParameters optional variable array of parameters to execute with the query

To iterate the result, use the callback.

Examples:

Simple query:

db.async().query("sql", "select from V", new AsyncResultsetCallback() {
  @Override
  public boolean onNext(Result result) {
    System.out.println( "Found record, name = " + result.getProperty("name"));
    return true;
  }

  @Override
  public void onError(Exception exception) {
    System.err.println("Error on executing query: " + exception );
  }
});

Query passing positional parameters:

db.async().query("sql", "select from V where age > ? and city = ?", new AsyncResultsetCallback(){
  @Override
  public boolean onNext(Result result) {
    System.out.println( "Found record, name = " + result.getProperty("name"));
    return true;
  }
}, 18, "Melbourne");

When you have multiple independent queries that could be executed in parallel, you could use the asynchronous interface and a CountDownLatch. The following example executes 3 queries in parallel and wait for all of them to have finished.

CountDownLatch counter = new CountDownLatch(3);

final ResultSet[] resultSets = new ResultSet[3];
database.async().query("sql", "select from X", resultset -> { resultSets[0] = resultset; counter.countDown(); });
database.async().query("sql", "select from Y", resultset -> { resultSets[1] = resultset; counter.countDown(); });
database.async().query("sql", "select from Z", resultset -> { resultSets[2] = resultset; counter.countDown(); });

// WAIT INDEFINITELY
counter.await();

// OR YOU CAN SPECIFY A TIMEOUT, LIKE 10 SECONDS TOP
// counter.await(10, TimeUnit.SECONDS);

query( language, command, callback, parameterMap )

Executes a query in asynchronous way, with optional named parameter. This method returns immediately. This method only executes idempotent statements, namely SELECT and MATCH, that cannot change the database. The execution of any other commands will throw a IllegalArgumentException exception.

Syntax:

void query( String language, String command, AsyncResultsetCallback callback,
            Map<String, Object> parameterMap )

Where:

  • language is the language to use

  • command is the command to execute If the language supports prepared statements (SQL does), you can specify parameters by name by using :<arg-name>

  • callback optional, is the callback that will be used for the whole lifecycle of the result set:

    • onStart() executed when the query is parsed and the first result ready

    • onNext() executed foreach result in the result set Return true to continue browsing the result set, otherwise false to interrupt fetching the result set

    • onComplete() executed when the entire result set is browsed, or the onNext() returned false to interrupt the browsing

    • onError() in case of any exception while executing the query

  • parameterMap this map is used to extract the named parameters

To iterate the result, use the callback.

Examples:

Map<String,Object> parameters = Map.of("age", 18, "city", "Melbourne");

db.async().query("sql", "select from V where age > :age and city = :city", new AsyncResultsetCallback(){
  @Override
  public boolean onNext(Result result) {
    System.out.println( "Found record, name = " + result.getProperty("name"));
    return true;
  }
}, parameters);

command( language, command, callback, positionalParameters )

Executes any command in asynchronous way, with optional positional parameters and callback. This method returns immediately.

Syntax:

void command( String language, String command,
            AsyncResultsetCallback callback,
            Object... positionalParameters )

Where:

  • language is the language to use

  • command is the command to execute If the language supports prepared statements (SQL does), you can specify parameters by using ? for positional replacement or by name by using :<arg-name> If the language supports prepared statements (SQL does), you can specify parameters by name by using :<arg-name>

  • callback optional, is the callback that will be used for the whole lifecycle of the result set:

    • onStart() executed when the query is parsed and the first result ready

    • onNext() executed foreach result in the result set Return true to continue browsing the result set, otherwise false to interrupt fetching the result set

    • onComplete() executed when the entire result set is browsed, or the onNext() returned false to interrupt the browsing

    • onError() in case of any exception while executing the query

  • positionalParameters optional variable array of parameters to execute with the query

To iterate the result, use the callback.

Examples:

Create a new record:

db.async().command("sql", "insert into V set name = 'Jay', surname = 'Miner'", new AsyncResultsetCallback() {
  @Override
  public boolean onNext(Result result) {
    System.out.println("Created new record: " + result.toJSON() );
    return true;
  }

  @Override
  public void onError(Exception exception) {
    System.err.println("Error on creating new record: " + exception );
  }
});

Create a new record by passing position parameters:

db.async().command("sql", "insert into V set name = ? surname = ?", new AsyncResultsetCallback() {
  @Override
  public boolean onNext(Result result) {
    System.out.println("Created new record: " + result.toJSON() );
    return true;
  }
}, "Jay", "Miner");

command( language, command, callback, parameterMap )

Executes any command in asynchronous way, with optional parameters passed in map format. This method returns immediately. It takes named parameters. Each parameter name (in the SQL query) is prefixed by a semicolon (:).

Syntax:

void command( String language, String command,
            AsyncResultsetCallback callback,
            Map<String, Object> parameterMap )

Where:

  • language is the language to use

  • command is the command to execute If the language supports prepared statements (SQL does), you can specify parameters by using ? for positional replacement or by name by using :<arg-name> If the language supports prepared statements (SQL does), you can specify parameters by name by using :<arg-name>

  • callback optional, is the callback that will be used for the whole lifecycle of the result set:

    • onStart() executed when the query is parsed and the first result ready

    • onNext() executed foreach result in the result set Return true to continue browsing the result set, otherwise false to interrupt fetching the result set

    • onComplete() executed when the entire result set is browsed, or the onNext() returned false to interrupt the browsing

    • onError() in case of any exception while executing the query

  • parameterMap this map is used to extract the named parameters

To iterate the result, use the callback.

Examples:

Create a new record by passing a map of parameters:

Map<String,Object> parameters = Map.of("name", "Jay", "surname", "Miner");

db.async().command("sql", "insert into V set name = :name, surname = :surname", new AsyncResultsetCallback() {
  @Override
  public boolean onNext(Result result) {
    System.out.println("Created new record: " + result.toJSON() );
    return true;
  }

  @Override
  public void onError(Exception exception) {
    System.err.println("Error on creating new record: " + exception );
  }
}, parameters);

transaction()

Executes a transaction in async mode. The transaction is executed in a separated thread. Example of use:

database.async().transaction( database -> {
  // EXECUTE OPERATIONS WITHIN TRANSACTION ASYNCHRONOUSLY
  // I.E.: database.command("sql", "update client set bonus = true where type = 'gold' and bonus is null");
  // I.E.: database.command("sql", "insert into notification set type = 'bonus', status = 'waiting', date = sysdate() ");
});

setParallelLevel( parallelLevel )

Changes the number of worker threads used for asynchronous operations. It is recommended to keep this number equal to or lower than the cores available on the machine. The initial value comes from the arcadedb.asyncWorkerThreads setting (see Settings).

Syntax:

void setParallelLevel( int parallelLevel )

Example:

database.async().setParallelLevel( 8 );

This call is safe to use while other threads have asynchronous work in flight on the same database. Growing the pool only adds workers and leaves the existing ones untouched. Shrinking it stops routing new work to the workers it retires and lets them finish the tasks already queued on them, so nothing already submitted is dropped and no unrelated caller is told the executor has shut down.

Because a shrink waits for the retired workers to finish, setParallelLevel() blocks until they have drained, up to an internal bound of ten seconds. If a worker is still busy inside user code when that bound expires, the call returns anyway, logs a warning, and leaves that worker finishing in the background - where it is still counted by waitCompletion() and isProcessing(). Treat this as an administrative call rather than something to invoke on a hot path.

setTransactionUseWAL( useWAL ) and setTransactionSync( flushType )

Set the durability policy the asynchronous executor applies to the transactions it opens. Turning the write-ahead log off makes bulk loading substantially faster at the cost of losing crash recovery for those transactions, which is why bulk-loading APIs such as GraphBatch use it.

Syntax:

void setTransactionUseWAL( boolean transactionUseWAL )
void setTransactionSync( WALFile.FlushType transactionSync )

Example:

database.async().setTransactionUseWAL( false );
database.async().setTransactionSync( WALFile.FlushType.NO );

Both take effect on the next task the executor runs, and apply to every task it runs, including DDL dispatched through command() with no wait for the response. A change made while a batch transaction is already open closes that transaction first, so records accumulated under the previous policy are always committed under the policy they were written with, never under the new one.


createRecord(record, newRecordCallback [,errorCallback])

Create a record in async way. Once the record is created in the database, the callback will be executed. This method returns immediately. The result can be managed in the NewRecordCallback callback and errors in ErrorCallback callback.

Syntax:

void createRecord(final MutableDocument record, final NewRecordCallback newRecordCallback,
                  final ErrorCallback errorCallback)

Where:

  • record is the mutable record to insert

  • newRecordCallback is the callback to handle the result after the record has been inserted

  • errorCallback (optional) is the callback to handle any error raised during insertion

Example on inserting a vertex asynchronously.

final MutableVertex vertex = database.newVertex("Customer").set("name", "Albert");
database.async().createRecord(vertex,
                              v -> { System.out.println("Record " + v.toJSON() + " created") });

updateRecord(record, updateRecordCallback [,errorCallback])

Updates a record in async way. Once the record is updated in the database, the callback will be executed. This method returns immediately. The result can be managed in the UpdatedRecordCallback callback and errors in ErrorCallback callback.

Syntax:

void updateRecord(final MutableDocument record, final UpdatedRecordCallback updateRecordCallback,
                  final ErrorCallback errorCallback)

Where:

  • record is the mutable record to update

  • updateRecordCallback is the callback to handle the result after the record has been updated

  • errorCallback (optional) is the callback to handle any error raised during update]

Example on inserting a vertex asynchronously.

database.async().updateRecord(vertex,
                              v -> { System.out.println("Record " + v.toJSON() + " updated") });

deleteRecord(record, deleteRecordCallback [,errorCallback])

Deletes a record in async way. Once the record is deleted from the database, the callback will be executed. This method returns immediately. The result can be managed in the DeletedRecordCallback callback and errors in ErrorCallback callback.

Syntax:

void deleteRecord(final Record record, final DeletedRecordCallback deleteRecordCallback,
                  final ErrorCallback errorCallback)

Where:

  • record is the record to delete

  • updateRecordCallback is the callback to handle the result after the record has been deleted

  • errorCallback (optional) is the callback to handle any error raised during deletion

Example on inserting a vertex asynchronously.

database.async().deleteRecord(vertex,
                              v -> { System.out.println("Record " + v.toJSON() + " updated") });