0

I have implemented service proxy class over the event bus, which has 2 methods (collect & cancel) collect method is taking 4 to 5 minutes to complete because it is over the network and collecting the data from the device.

But in between collecting the data if I am calling the cancel on the service proxy which will usually stop the collecting the data from the device is not calling.

The cancel method is waiting to complete the collect method and then request is coming into cancel.

I have 2 verticles one for handling HTTP requests and second is for collecting the data,.

CollcetionServiceProxy class is exposed over event bus through CollectionVerticle which I am deploying as a worker verticle.

At the time of deployment, If I deploy 2 instances of CollectionVerticle It works fine But I don't want to do that.

How Can I resolve this issue with Single Verticle Instance of collection.

Ravat Tailor
  • 1,193
  • 3
  • 20
  • 44

2 Answers2

0

A approach you could take is to send the request over the EventBus to start collection. The response would be just an acknowledgement. Your collector verticles would send data to a temp address the original request had stated. In each iteration of the loop the collector checks an “isCanceled” flag for the request which could be set by the other action. Bonus track: wrap that into a flowable, so your business logic doesn’t need to know the eventbus Mechanic below it. I described something like that recently.

To be very clear. When your code looks like this:

WorkerExecutor executor = vertx.createSharedWorkerExecutor("my-worker-pool");
executor.executeBlocking(promise -> { 
// Call some blocking API that takes a significant amount of time to return
 String result = someAPI.blockingMethod("hello");
 promise.complete(result); },
 res -> { System.out.println("The result is: " + res.result());
});

NOTHING will interrupt your someAPI.blockingMethod("hello"); call. The only thing you could do is to fail the promise at the end.

However, and I presume that's the case here, you wrote the someAPI (to some extend). then you could do something like this:

public class CollectorVerticle extends AbstractVerticle {
    private final ConcurrentMap <long, AtomicBoolean> cancelTracker = new ConcurrentHashMap<>();
...

Inside your execution:

final long key = Date.getTime(); // We use a Milisecond as key
executor.executeBlocking(promise -> { 
// Call some blocking API that takes a significant amount of time to return
    StringBuilder result = new StringBuilder();
someAPI.fixedblockingMethod(result, cancelTracker, key, "hello");
 promise.complete(result.toString());
 },
 res -> {
    if res.succeeded() {
       System.out.println("The result is: " + res.result());
    } else {
      // Do whatever - check for error etc
    }
    cancelTracker.remove(key);
});

} 

Then in your method along these lines:

fixedblockingMethod(StringBuilder b, Map cancelTracker, long key, String whatever) {

  for (int i =0; i < eternity; i++) {
      if (!cancelTracker.get(key).get() {
        break;
      }
      b.append(getNextItemFromInterface();
  }
}

That should do the trick. I would still send individual items over the eventbus instead of collecting on the blocking method

stwissel
  • 20,110
  • 6
  • 54
  • 101
  • In my CollectionVerticle, I am running a blocking code in WorkerExecuter, Which I think doesn't run on the same event loop or it used different thread pool. – Ravat Tailor Jan 05 '20 at 14:45
  • like : WorkerExecutor executor = vertx.createSharedWorkerExecutor("my-worker-pool"); executor.executeBlocking(promise -> { // Call some blocking API that takes a significant amount of time to return String result = someAPI.blockingMethod("hello"); promise.complete(result); }, res -> { System.out.println("The result is: " + res.result()); }); – Ravat Tailor Jan 05 '20 at 14:45
  • you need to change `someAPI.blockingMethod` to check for abortion. See my extended answer above – stwissel Jan 05 '20 at 15:58
  • My Concern is I want to put all same type of methods in one service proxy class – Ravat Tailor Jan 05 '20 at 16:39
  • By Same class, I can call the method on one queue instead of creating different queues – Ravat Tailor Jan 05 '20 at 17:12
  • You might want to step back and look at the problem to solve, rather than insisting on the solution approach you are stuck with. Elaborate more on “one queue”. What do you mean with that? – stwissel Jan 05 '20 at 23:41
  • one queue means, I am exposing service proxy class on the event bus on one address like "collection-event", which will do collection related stuff and that service Proxy class have collect and cancel method. – Ravat Tailor Jan 06 '20 at 06:55
  • one queue means, I am exposing service proxy class on the event bus on one address like "collection-event", which will do collection related stuff and that service Proxy class have collect and cancel method. – Ravat Tailor Jan 06 '20 at 06:55
  • That’s UP - how external services see the collection-event. The internal implementation could be different – stwissel Jan 06 '20 at 15:37
0

base on your code sample

WorkerExecutor executor = vertx.createSharedWorkerExecutor("my-worker-pool"); 
  executor.executeBlocking(promise -> { // Call some blocking API that takes significant amount of time to return String result = 
  someAPI.blockingMethod("hello"); 
  promise.complete(result); 
}, res -> { 
  System.out.println("The result is: " + res.result()); 
});

you are looking to stop blocking code, by the name of it, blocking code cannot be stoped till it end

so one approach will be to make this blocking code check periodically if it should be canceled

one implementation will be to make your blocking code return a completable future, and cancel it on event

shahaf
  • 4,750
  • 2
  • 29
  • 32