Strange behavior of the Async-API


#1

Hi,

I have observed very strange behavior of the Async-API of the client. If the implementation of the method RecordListener.onSuccess() throws some kind of runtime exception, the API calls immediately RecordListener.onFailure() on the same RecordListener instance (i.e. both onSuccess() and onFailure() gets called for the same instance ). This is quite unexpected und inconsequent behavior and looks to me like a bug. If it is intended, what is the reason for this?

Cheers,

Assen


#2

Can you point to the specific code that you are referring to? Thanks.


#3

Hi,

Yes, please find below reproducer for this issue. My aerospike client version is 3.1.2 :

  final AsyncClient client = new AsyncClient("localhost", 3000);
  final RecordListener listener = new RecordListener()
  {
     @Override
     public void onSuccess(final Key key, final Record record)
     {
        System.out.println("onSuccess() gets called for " + hashCode());
        throw new ClassCastException("Now onFailure() will be triggered.");
     }

     @Override
     public void onFailure(final AerospikeException exception)
     {
        System.out.println("onFailure() gets called for " + hashCode());
     }
  };
  client.get(new Policy(), listener, new Key("myNameSpace", "mySetName", "someKey"));

Regards,

Assen


#4

If the onSuccess() callback throws an exception, onFailure() is intentionally called. This was done because some customers had wait()/notify() logic in some of their code.

If an unexpected exception occurred before the command completed notify() logic in onSuccess(), then calling onFailure() will trigger notify(). Otherwise, the wait() logic will wait forever because notify() will not be called.

In general, it’s good practice to handle all exceptions in onSuccess(). This is the reason that checked exceptions are not allowed in onSuccess() interface callbacks. There is no way to prevent runtime exceptions from being thrown, so they are caught and onFailure() is called.