Reactor 3 Custom Data Flow--response spring's DAO spell device

Source: Internet
Author: User
Tags emit generator static class

This series of articles index the "Response Spring's word Wizard"
Previously feed-response Flow | Reactor 3 Quick Start | Responsive Flow Specification
This article source

2.2 Custom Data Flow

This section describes how to onNext onError onComplete Create a Flux or Mono by defining the appropriate events (, and). Reactor provides, and, generate create push and handle so on, all of these methods use sink (pools) to generate data streams.

Sink, as the name implies, is the pool, you can imagine the kitchen pool look. As shown in the following:

The methods described below have a sink provided to the method user, usually exposing at least three methods to us, next error and complete . Next and error are equivalent to two drains, and we keep putting the custom data into next, and reactor will string us into a publisher stream until a wrong data is put to the error port, or a button is clicked complete , and the data flow terminates.

2.2.1 Generate

generateis a way to emit data on a synchronous basis. Because the sink it provides is one SynchronousSink , and its next() method can only be called once per callback.

generateThere are three types of signatures for this method:

    public static <T> Flux<T> generate(Consumer<SynchronousSink<T>> generator)    public static <T, S> Flux<T> generate(Callable<S> stateSupplier, BiFunction<S, SynchronousSink<T>, S> generator)     public static <T, S> Flux<T> generate(Callable<S> stateSupplier, BiFunction<S, SynchronousSink<T>, S> generator, Consumer<? super S> stateConsumer)

1) using Synchronoussink to generate data streams

    @Test    public void testGenerate1() {        final AtomicInteger count = new AtomicInteger(1);   // 1        Flux.generate(sink -> {            sink.next(count.get() + " : " + new Date());   // 2            try {                TimeUnit.SECONDS.sleep(1);            } catch (InterruptedException e) {                e.printStackTrace();            }            if (count.getAndIncrement() >= 5) {                sink.complete();     // 3            }        }).subscribe(System.out::println);  // 4    }
    1. Used for counting;
    2. Put custom data into the pool;
    3. Tell generate the method that the custom data has been sent out;
    4. Triggers the data flow.

The output is printed every 1 seconds for a total of 5 printing times.

2) Add a companion state

For the above example, count for the record state, the count is stopped when the value reaches 5. Because it is used inside a lambda, it must be of the final type and cannot be a primitive type (such as int ) or an immutable type (such as Integer ).

If you use the second method signature, the above example can be changed like this:

    @Test    public void testGenerate2() {        Flux.generate(                () -> 1,    // 1                (count, sink) -> {      // 2                    sink.next(count + " : " + new Date());                    try {                        TimeUnit.SECONDS.sleep(1);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    if (count >= 5) {                        sink.complete();                    }                    return count + 1;   // 3                }).subscribe(System.out::println);    }
    1. Initializes the state value;
    2. The second argument is BiFunction that the input is state and sink;
    3. Each cycle returns a new status value for the next use.

3) Complete post-processing

The third method signature in addition to the state, sink, there is one, which is Consumer Consumer executed after the data flow has been sent out.

        Flux.generate(                () -> 1,                (count, sink) -> {                    sink.next(count + " : " + new Date());                    try {                        TimeUnit.SECONDS.sleep(1);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    if (count >= 5) {                        sink.complete();                    }                    return count + 1;                }, System.out::println)     // 1                .subscribe(System.out::println);    }
    1. Finally, the count value is printed out.

If state uses a database connection or other resource that needs to be cleaned, this Consumer lambda can be used to finalize the resource cleanup task.

2.2.2 Create

createis a more advanced method of creating flux, which can generate data streams either synchronously or asynchronously, and can emit multiple elements at a time.

createUse, the FluxSink latter also provides methods such as Next,error and complete. Unlike generate, create does not require a state value, and on the other hand, it can trigger multiple events in the callback, even if the event occurs at some time in the future.

The common scenario for create is to turn an existing API into a responsive one, such as a listener's async method.

Write an event source first:

  public class Myeventsource {private list<myeventlistener> listeners;        Public Myeventsource () {this.listeners = new arraylist<> ();        } public void register (MyEventListener listener) {//1 listeners.add (listener);                } public void Newevent (MyEvent event) {for (MyEventListener listener:listeners) {     Listener.onnewevent (event);                    2}} public void eventstopped () {for (MyEventListener listener:      Listeners) {listener.oneventstopped (); 3}} @Data @NoArgsConstructor @AllArgsConstructor public static class My            Event {//4 private Date timestemp;        Private String message; }    }
    1. Register the Listener;
    2. Issue a new event to the listener;
    3. Tells the listener that the event source has stopped;
    4. event class, using the Lombok annotation.

Prepare a listener interface that can listen for two events on the top 2nd and 3: (1) New arrivals, and MyEvent (2) event sources to stop. As follows:

    public interface MyEventListener {        void onNewEvent(MyEventSource.MyEvent event);        void onEventStopped();    }

The following test method logic is: Create a listener registered to the event source, the listener receives the event callback again when the Flux.create sink to convert a series of events into an asynchronous stream of events:

    @Test public void Testcreate () throws interruptedexception {Myeventsource EventSource = new Myeventsource ()    ;                        1 flux.create (sink, {eventsource.register) (new MyEventListener () {//2                            @Override public void Onnewevent (Myeventsource.myevent event) {       Sink.next (event);                            3} @Override public void oneventstopped () {        Sink.complete ();                4}});       }). Subscribe (system.out::p rintln);            5 for (int i = 0; i <; i++) {//6 random random = new random ();            TimeUnit.MILLISECONDS.sleep (Random.nextint (1000));          Eventsource.newevent (New Myeventsource.myevent (New Date (), "event-" + i)); } eventsource.eventstopped (); 7}
    1. Event source;
    2. Registers a listener created with an anonymous inner class to the event source;
    3. The listener sends the event back through sink when the event callback is received;
    4. When the listener receives a callback from the source stop, it sends the completion signal through the sink;
    5. Trigger the Subscription (no event has been generated at this time);
    6. The loop produces 20 events, each with a random time of no more than 1 seconds;
    7. Last stop event source.

Run this test method, 20 MyEvent print out in succession.

If the above method is replaced with a create generate method, an exception is reported:

java.lang.IllegalStateException: The generator didn‘t call any of the SynchronousSink method

proves that generate the asynchronous approach is not supported.

createMethod also has a Variant method push that is suitable for generating event streams. With create 类似, push can also be asynchronous and be able to use the various back-pressure strategies above. So the above example can be replaced with a push method. The difference is that, push in a method, the call next , complete or error the same thread must be the same.

In addition to next , complete or error methods, FluxSink There are onRequest methods that can be used to respond to a downstream subscriber's request event. Thus not only can the upstream be pushed downstream when the data is ready, as in the previous example, but downstream can also pull data that is already ready from the upstream. This is a push/pull blending pattern. Like what:

    Flux<String> bridge = Flux.create(sink -> {        myMessageProcessor.register(          new MyMessageListener<String>() {            public void onMessage(List<String> messages) {              for(String s : messages) {                sink.next(s);   // 1              }            }        });        sink.onRequest(n -> {   // 2            List<String> messages = myMessageProcessor.request(n);  // 3            for(String s : message) {               sink.next(s);             }        });        ...    }
    1. Push mode, the initiative to send data downstream;
    2. Called when a downstream request is made;
    3. Responds to downstream requests and queries for a message that is available.

Reactor 3 Custom Data Flow--response spring's DAO spell device

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: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.