Java implementation of asynchronous callback interface by time gradient

Source: Internet
Author: User

1. Background

After the business process, you need to call other system interfaces, the corresponding processing results are notified to the other side, if the synchronous request, if the system is called abnormal or down events, it will cause its own business is affected, the transaction will be blocked, the database connection is not enough, such as abnormal phenomena, can be asynchronous callback to prevent blocking, But there is a problem with the asynchronous situation, if the call is unsuccessful, what happens next? This place needs to be in the time gradient callback, such as the early press 10s interval callback, callback 3 times, if not successfully press the 30s callback, callback 2 times, or not successfully by the minute callback, and so on ... Equivalent to the other side of the system to restore the time, can not always be in an abnormal state or downtime, such as abnormal status, if it is not successful again through the means of manual intervention to deal with, specific business implementation.

2. Technology implementation

The general realization of the idea, such as this process with two queues, the current queue and next queue, the current queue is used to hold the first callback data object, if the call is not successful in the next queue, according to the established time policy to continue the callback until the successful or final persistence after the manual access processing.

  The following techniques are used:

    • HTTP request Library, Retrofit2
    • Queue, Linkedblockingqueue
    • Dispatch thread pool, Scheduledexecutorservice

3. Main code Description

Strategy design of 3.1 callback time gradient

The enumeration is used to process the policy rules, which facilitates the maintenance of the code, which designs three parameters, level, callback interval and number of callbacks;

/*** Callback Policy*/ Public enumCallbacktype {//level 1,10s performed 3 timesSECONDS_10 (1, 10, 3),    //level 2,30s performed 2 timesSeconds_30 (2, 30, 2),    //level 3,60s performed 2 timesMinute_1 (3, 60, 2),    //level 4,5min performed 1 timesMinute_5 (4, 300, 1),    //level 5,30min performed 1 timesMinute_30 (5, 30*60, 1),    //level 6,1h performed 2 timesHour_1 (6, 60*60, 1),    //level 7,3h performed 2 timesHour_3 (7, 60*60*3, 1),    //level 8,6h performed 2 timesHour_6 (8, 60*60*6, 1); //level    Private intLevel ; //callback interval time seconds    Private intIntervalTime; //Number of callbacks    Private intcount;}

3.2 Data Transfer Object design

Declares an abstract parent class, making it easier for other objects to invoke transport inheritance.

/*** Message Object parent class*/ Public Abstract classMessageinfo {//Start Time    Private LongStartTime; //Update Time    Private LongUpdateTime; //whether the callback succeeded    Private Booleanissuccess=false; //Number of callbacks    Private intCount=0; //Callback Policy    Privatecallbacktype Callbacktype;}

The object to transfer, inheriting the message parent class;

/*** Ticket Callback information*/ Public classWorkordermessageextendsMessageinfo {//Frame Number    PrivateString vin; //Ticket number    PrivateString Workorderno; //Work order Status    PrivateInteger status; //Work Order Reason    PrivateString reason; //Manipulating Users    PrivateInteger userid;}

3.3 Use of the scheduling thread pool

//declaration thread pool, sizePrivateScheduledexecutorservice pool = Executors.newscheduledthreadpool (16);
... Slightly while(true){ //get the data from the queue and give it to the timer execution Try{workordermessage message=Messagequeue.getmessagefromnext (); LongExcuetime = Message.getupdatetime () +message.getcallbacktype (). Getintervaltime () * 1000; Longt = excuetime-System.currenttimemillis (); if(t/1000 < 5) {//the data to be executed within 5s is submitted to the dispatch thread poolSYSTEM.OUT.PRINTLN ("Messagehandlenext-meets timer execution condition" +jsonobject.tojsonstring (message)); Pool.schedule (NewCallable<boolean>() {@Override PublicBoolean Call ()throwsException {remotecallback (message); return true; }}, T, Timeunit.milliseconds); }Else{messagequeue.putmessagetonext (message); } } Catch(interruptedexception e) {System.out.println (e); } }

3.4 Retrofit2 is easy to use.

Specific to see the official website related documents to understand, use up or more convenient.

Retrofit initialization:

ImportRetrofit2. Retrofit;Importretrofit2.converter.gson.GsonConverterFactory; Public classRetrofithelper {Private Static FinalString Http_url = ""; Private StaticRetrofit Retrofit;  Public StaticRetrofit Instance () {if(Retrofit = =NULL) {Retrofit=NewRetrofit.builder (). BASEURL (Http_url). Addconverterfactory (gsonconverterfactory        . Create ()). build (); }        returnRetrofit; }}

If you need to modify the time-out period, the connection time and so on can be initialized, retrofit using okhttpclient

ImportOKHTTP3. okhttpclient;ImportRetrofit2. Retrofit;Importretrofit2.converter.gson.GsonConverterFactory;ImportJava.util.concurrent.TimeUnit; Public classRetrofithelper {Private Static FinalString Http_url = ""; Private StaticRetrofit Retrofit;  Public StaticRetrofit Instance () {if(Retrofit = =NULL) {Retrofit=NewRetrofit.builder (). BASEURL (Http_url). Client (NewOkhttpclient.builder (). ConnectTimeout (, Timeunit.seconds)//Connection Time. ReadTimeout (Timeunit.seconds)//Read Time. WriteTimeout (Timeunit.seconds)//Write Time. Build ()). Addconverterfactory (Gsonconverterfactory.create ())        . build (); }        returnRetrofit; }}

Retrofit using an interface call, first declare an interface;

Import; Import Com.woasis.callbackdemo.bean.WorkOrderMessage; Import Retrofit2. Call; Import Retrofit2.http.Body; Import Retrofit2.http.POST;  Public Interface workordermessageinterface {    @POST ("/api")    call <JSONObject>  Updatebatteryinfo (@Body workordermessage message);}

The interface and the instance object are ready, and then the call is made;

Private voidremotecallback (Workordermessage message) {//instance Interface ObjectWorkordermessageinterface workordermessageinterface = Retrofithelper.instance (). Create (Workordermessageinterface.class); //Calling interface MethodsCall<jsonobject> Objectcall =workordermessageinterface.updatebatteryinfo (message); System.out.println ("Remote Call Execution:" +NewDate ()); //Asynchronous Call ExecutionObjectcall.enqueue (NewCallback<jsonobject>() {@Override Public voidOnresponse (call<jsonobject> call, response<jsonobject>response) {System.out.println ("messagehandlenext**** Call succeeded" +Thread.CurrentThread (). GetId ()); Message.setsuccess (true); System.out.println ("Messagehandlenext-Callback succeeded" +jsonobject.tojsonstring (message)); } @Override Public voidOnFailure (call<jsonobject>Call , Throwable throwable) {System.out.println ("messagehandlenext++++ call failed" +Thread.CurrentThread (). GetId ()); //failed to put data into queue                Try {                    //Initialize the callback policy                    LongCurrentTime =System.currenttimemillis ();                    Message.setupdatetime (currenttime); Message.setsuccess (false); Callbacktype Callbacktype=Message.getcallbacktype (); //Get Rank                    intLevel =Callbacktype.getlevel (Callbacktype); //number of fetches                    intCount =Callbacktype.getcount (Callbacktype); //If the level is already the highest, no callback                    if(CallbackType.HOUR_6.getLevel () = = Callbacktype.getlevel () && count = =Message.getcount ()) {System.out.println ("messagehandlenext-rank highest, no longer callback, offline Processing:" +jsonobject.tojsonstring (message)); }Else {                        //to see if Count is the largest, count the maximum to increase the level                        if(Message.getcount () <Callbacktype.getcount ()) {Message.setcount (Message.getcount ()+1); }Else{//if not small, increase the levelMessage.setcount (1); level+ = 1;                        Message.setcallbacktype (level) (Callbacktype.gettypebylevel);                    } messagequeue.putmessagetonext (message); }                } Catch(interruptedexception e) {e.printstacktrace (); System.out.println ("Messagehandlenext-failed to put queue data");    }            }        }); }

3.5 Results achieved

4. Summary

The implementation of the time gradient to the corresponding other system interface, no longer cause its own business due to the exception of other systems and blocked. Ask the big boys to see if there is any unreasonable place, welcome to criticize.


Related Article

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.