I want to support both Synchronous and Asynchronous call using RESTEasy-JAXRS. And my asynchronous call should be based on callback, where Async request will have callbackURI, request gets processed asynchronously and upon completion makes a call to callbackURI with operation status/result. Can someone point me out to correct place? I see lot about polling model, but not callback with RESTEasy.
I am new to Asynchronous stuff...
Thanks in advance!
Thanks for your response rmlan.Yes but we have support in JAX-RS to handle asynchronous using #Suspended & AsyncResponse. I did that with following code, but i am unable to find the way to make callback to Client who called the API upon completion of task with this request.
#GET
#Path("/async")
public String checkAsync(#Suspended final AsyncResponse response) {
response.setTimeoutHandler(new TimeoutHandler() {
#Override
public void handleTimeout(AsyncResponse asyncResponse) {
response.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE)
.entity("Operation time out.").build());
}
});
response.setTimeout(2, TimeUnit.SECONDS);
new Thread(new Runnable() {
#Override
public void run() {
String result = veryExpensiveOperation();
response.resume(result);
}
private String veryExpensiveOperation() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.debug("Task is processed fully");
return "Successful";
}
}).start();
return "nothing";
}
Every method in class has one return ( or maybe void ) . but sometimes you need some callbacks from your method . this is the solution .
public abstract class MyClass {
public abstract void myCallbackMethod();
public void myMethod(){
for (int i = 0; i < 5; i++) {
// do somthing
myCallbackMethod();// it will implements in future.
}
}
}
when you make an object from MyClass , you must implement myCallbackMethod abstract method . like this
public class NewMain {
public static void main(String[] args) {
MyClass myClass=new MyClass() {
#Override
public void myCallbackMethod() {
System.err.println("this is call back");
}
};
myClass.myMethod();
}
}
and the result is
this is call back
this is call back
this is call back
this is call back
this is call back
it means you can get five call backs from void method in your class.
it is a good way when you do not have any idea for the body content of myCallBackMethod
the real example is download a file from server in your app .
you can call myCallBackMethod when bytes received and progress your progressbar
Related
I'm fairly new to RxJava and I have a basic understanding as to how to wrap a callback into an Observable but what I'm having difficulty with is doing so when the callback/listener is pre-instanced. Every example that I have found only shows instancing the callback directly into the Observable being created.
Some example code of what I'm talking about. I'm working with an Api that's works like this:
public class Api {
private ApiCallback callback;
void initialize(ApiCallback callback){
this.callback = callback;
}
void doAction1(){
this.callback.onAction1Complete();
}
}
interface ApiCallback {
void onInitialized();
void onAction1Complete();
}
With the real api I am working with I have no control over how it works so I must work with it in this state. In terms of trying to work with this Api using observables here is the struggle I am having. I have a member variable that holds the Api object:
private Api mApi = new Api();
Now in order to initialize this I have one of two options it seems.
Option 1:
Completable startApi() {
return Completable.create(new CompletableOnSubscribe() {
#Override
public void subscribe(final CompletableEmitter emitter) throws Exception {
mApi.initialize(new ApiCallback() {
#Override
public void onInitialized() {
emitter.onComplete();
}
#Override
public void onAction1Complete() {
}
});
}
});
}
Option 2:
private ApiCallback premadeCallback = new ApiCallback() {
#Override
public void onInitialized() {
}
#Override
public void onAction1Complete() {
}
};
Completable startApi() {
return Completable.create(new CompletableOnSubscribe() {
#Override
public void subscribe(final CompletableEmitter emitter) throws Exception {
mApi.initialize(premadeCallback);
}
});
}
Now the issue I have is that Option 2 makes more sense to me when I need to know when the other methods in the callback are called from Api calls. With my understanding of RxJava however I don't understand how I can reach these method calls with an Api that works like this.
For example:
Completable doAction1() {
return Completable.create(new CompletableOnSubscribe() {
#Override
public void subscribe(final CompletableEmitter emitter) throws Exception {
// Api is already initialized with callback
// How do I reach the callback from here?
}
});
}
The only what that I can currently think of as to how to achieve this would be to create a member variable as an emitter (or a dictionary of emitters) and then call its appropriate method in the api callback when needed. My concerns with this are A. I'm unsure if RxJava can work this way B. This sounds like a terrible idea.
I'm implementing a layer to wrap a 3rd party communication layer.
The contract I need to implement is:
FutureTask<SomeData> send(Request request);
My layer has an onMessageReceived method, which is called by the 3rd party when a response arrives.
The approach I've taken to implement my layer is as follows:
I have a callable, which waits on a condition with a timeout:
interface MyCallable<T> extends Callable<T> {
void signal();
}
class CallableWithSignal<T> implements MyCallable<T> {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private long waitTime;
public CallableWithSignal(int waitTimeSeconds){
this.waitTime=waitTimeSeconds;
}
#Override
public T call() throws Exception {
lock.lock();
try {
boolean wasSignaled = condition.await(waitTime, TimeUnit.SECONDS);
if(wasSignaled)
return null;
System.out.println("throwing exeption");
throw new Exception("timeout");
} finally {
lock.unlock();
}
}
#Override
public void signal() {
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}
}
I also have extended FutureTask to expose the set method, as follows:
class MyFutureTask<V> extends FutureTask<V> {
private MyCallable<V> myCallable;
public MyFutureTask(MyCallable<V> r) { super(r); myCallable = r;}
#Override
public void set(V x) { super.set(x); }
#Override
public void setException(Throwable t) { super.setException(t); }
#Override
protected void done() {
super.done();
myCallable.signal();
}
}
When the task is done, I signal the callable to stop it.
So every time a send is called, I create a new MyFutureTask, run it using an executor, save it in a map and return it.
When onMessageReceived is called I find the task in the map and set its result with the set method.
Is this a good approach?
And another question: is it a good approach to move the executor logic inside the task? I mean, to create a start method for it, which will run the task using the executor.
please advice.
The below method onReceivedTitlegets called 2-3 times with in a second when webview url changes. I want to call a method in it, when onReceivedTitle is being called last time. I am doing this because I just want to monitor url changes with in webview. shouldOverrideUrlLoading is not getting called when url changes through ajax.
class MyWebChromeClient extends WebChromeClient {
#Override
public void onReceivedTitle(WebView view, String title) {
Log.v("onReceivedTitle", "=>" + title);
// callAMehod();
super.onReceivedTitle(view, title);
}
}
If you want to throttle how often a method call causes another method call you can do so for example via a Handler. The simplest version enqueues a delayed message on the first call and any subsequent call while there is an enqueued message will not enqueue a new one. That results in 1 call every X time to go though - but it take at least that amount of time until the first action happens.
Example implementation (you can put that class unmodified somewhere in your code)
public abstract class ThrottleExecutor {
private final long mMinDelay;
public ThrottleExecutor(long minDelay) {
mMinDelay = minDelay;
}
/** Implement to do something */
public abstract void doThrottled();
public final void scheduleExecution() {
if (mHandler.hasMessages(0)) {
// message already enqueued, do nothing
} else {
// otherwise enqueue a message for later
mHandler.sendEmptyMessageDelayed(0, mMinDelay);
}
}
public final void cancelExecution() {
mHandler.removeMessages(0);
}
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message msg) {
doThrottled();
}
};
}
And then use it for example like so
class Usage {
private ThrottleExecutor mThrottle = new ThrottleExecutor(2000) {
#Override
public void doThrottled() {
// happens at most every 2000ms
methodToBeThrottled();
}
};
void methodThatHappensTooOften() {
mThrottle.scheduleExecution();
}
void methodToBeThrottled() {
Log.d("TAG", "triggered at 2000ms before");
}
}
You might want to use Handler and do something like this:
class MyWebChromeClient extends WebChromeClient {
private boolean mOnReceivedTitleInvoked;
#Override
public synchronized void onReceivedTitle(final WebView view, final String title) {
if (!mOnReceivedTitleInvoked) {
mOnReceivedTitleInvoked = true;
Log.v("onReceivedTitle", "=>" + title);
handler.postDelayed(new Runnable() {
#Override
public void run() {
super.onReceivedTitle(view, title);
mOnReceivedTitleInvoked = false;
}
}, 1000);
}
}
}
Although you might want to reconsider the onReceivedTitle behaviour.
Based on guava-libraries example, I am using ListenableFuture.
I am using:
java 1.6
JDeveloper 11.1.1.6.0
guava-13.0.1.jar
junit-4.5.jar
easymock-3.1.jar
powermock-easymock-1.4.12-full.jar
I am trying to ensure that method under test is called in async mode.
My Manager.java code is:
...
public synchronized void refreshAsync(final String id) {
m_Log.entry(id);
ListeningExecutorService service =
MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
ListenableFuture<Details> getDetailsTask =
service.submit(new Callable<Details>() {
#Override
public Details call() {
System.out.println(Thread.currentThread().toString());
return MyCacheManager.getDetails(id);
}
});
Futures.addCallback(getDetailsTask ,
new FutureCallback<Details>() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Details details) {
System.out.println("Success");
//TODO: publish event
}
public void onFailure(Throwable thrown) {
System.out.println("Failed");
//TODO: log
}
});
service.shutdown();
m_Log.exit("done async");
}
...
My test is:
#RunWith(PowerMockRunner.class)
#PrepareForTest( { Manager.class, MyCacheManager.class, TWResourceManager.class, Logger.class })
public class DetailsTests {
{
...
#Test (timeout = 4000)
public void refreshAsync_RequestedInAsyncMode_NoWaitForComplete() throws Exception {
// Creating nice mock - because we are not caring about methods call order
mockStatic(MyCacheManager.class);
// Setup
final int operationTimeMilis = 5000;
expect(MyCacheManager.getDetails(anyObject(String.class))).andStubAnswer(new IAnswer<Details>() {
public Details answer() {
try {
System.out.println("start waiting 5 sec");
System.out.println(Thread.currentThread().toString());
Thread.sleep(operationTimeMilis);
System.out.println("finished waiting 5 sec");
} catch (InterruptedException e) {
e.printStackTrace();
}
return Details.getEmpty();
}
});
replay(MyCacheManager.class);
replayAll();
ISchemaActionsContract controller = new TWManager();
controller.refreshSchemaDetailsAsync("schema_id");
// We need not to verify mocks, since all we are testing is timeout
// verifyAll();
}
}
When I am running / debugging the test - it is always failed on timeout. It seems that mocked method "MyCacheManager.getDetails" is called in "sync" mode.
But when I am calling same function from regular code / debug - it is running in async mode (I put Thread.sleep(10000) into MyCacheManager.getDetails method, and Manager.refreshAsync method is exited without waiting / be blocked.
Also, If I am changing the method to use regular FutureTask, test pass as expected.
...
Object res = null;
FutureTask task = new FutureTask(new Runnable() {
#Override
public void run() {
MyCacheManager.getDetails(id);
}
}, res);
m_Log.debug("async mode - send request and do not wait for answer.");
Executors.newCachedThreadPool().submit(task);
Any idea will be more then welcome! :)
Thanks!
I am trying to understand mechanism of callback handler. How is the handle() method invoked? Can anybody give an example of usage of custom callback handler (other than those used in Login Modules of JASS or so) in non Swing application?
Define an interface to handle the callback.
public interface ServiceListener<T> {
void callback(T result);
}
Define a method that takes ServiceListener as parameter and returns void.
Public void runInBackground(ServiceListener listener) {
...code that runs in the background...
listener.callback(...data to return to caller...);
}
And you can now do this from your main code:
runInBackground(new ServiceListener() {
#Override
public void callback(..returned data...) {
...Do stuff with returned data...
}
});
This is a basic example for requesting data from a webserver using the AsyncTask from an Android application.
First define the async class. Note that the constructor takes a listener which we use to publish the result once ready.
public class Webservice extends AsyncTask<String, Void, String> {
private DialogListener dialogListener;
public Webservice(final DialogListener dialogListener) {
this.dialogListener = dialogListener;
}
#Override
protected String doInBackground(final String... strings) {
// We cant trigger onComplete here as we are not on the GUI thread!
return "";
}
protected void onPostExecute(final String result) {
dialogListener.onComplete(result);
}
}
Basic server class for handling various network communications:
public class Server {
public void queryServer(final String url, final DialogListener service) {
// Simulate slow network...
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Webservice(service).execute(url);
}
}
We can now use this code inside our activity without having to worry how long the call takes as it is not going to halt the GUI as it is executed async.
Server s = new Server();
// Async server call.
s.queryServer("http://onto.dk/actions/searchEvents.jsp?minLatE6=55640596&minLngE6=12078516&maxLatE6=55642654&maxLngE6=12081948", new DialogListener() {
#Override
public void onComplete(final String result) {
toast("complete");
}
#Override
public void onError() {
toast("error");
}
});