Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Silent Revolution by Max Voronoy (Senior Consultant, Engineering, Globallogic)

21 Aufrufe

Veröffentlicht am

- Reactive programming
- Spring 5
- MT Examples etc.

Veröffentlicht in: Ingenieurwesen
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Silent Revolution by Max Voronoy (Senior Consultant, Engineering, Globallogic)

  1. 1. BAD MT EXAMPLES try(Transaction t = db.startTransaction()){ List<User> all = db.select10000Users(); all.forEach(u->{ String text = template.formatEmail(u); smtp.send(u.email, text); }); } Future<?> future = executorService.submit(() -> { String threadName = Thread.currentThread().getName(); System.out.println("Hello " + threadName); }); future.get(); • NO MT CODE private Lock synchro = new ReentrantLock(); public void wrong2(Map<String, String> sharedResource) { synchro.lock(); try{ sharedResource.put("Key1", "Value1"); }finally { synchro.unlock(); } } • ERROR IN PRIMITIVE USE • ERROR IN RESPONSIBILITY AND TRANSACTION SCOPE class Singleton //doublecheck { static volatile Singleton instance; static Object accessor… static Singleton get() { if(instance == null){ lock(accessor){ if(instance == null) instance = new; } } return instance; } } • BROKEN PATTERN
  2. 2. WHERE IS MY CPU • BAD CPU UTILIZATION • NO LOAD RESERVE
  3. 3. EVERYBODY LIKES SPRING ( ) ReactiveX Reactor IO • NETTY, JETTY, TOMCAT, UNDERTOW (SERVLET 3.1 ) • JDK 9 AS JAVA.UTIL.CONCURRENT.FLOW • > JAVA.NIO.FILE.*(AsynchronousFileChannel) • HTTP | WEBSOCKET | TCP | UDP Streams
  4. 4. THINK REACTIVE event Iterable (pull) Observable (push) retrieve data T next() onNext(T) discover error throws Exception onError(Exception) complete !hasNext() onCompleted()
  5. 5. BASIC PLAYERS (FROM REACTOR.IO) • SUBSCRIBER • PUBLISHER • FLUX -> 0:N (∞) • MONO -> 0:1 public void subscribe(Subscriber<? super T> s); // Factory for Subscription interface void onSubscribe(Subscription s); void onNext(T t); void onError(Throwable t); void onComplete();
  6. 6. LET’S RUN SIMPLE Flux.just("red", "white", "blue") .log() .map(value -> value.toUpperCase()) .subscribe(System.out::println); Flux.just("red", "white", "blue") .subscribeOn(Schedulers.parallel()) // !!!! .log() .map(value -> value.toUpperCase()) .subscribe(System.out::println); 01:37:18.678 [main] INFO reactor.core.publisher.FluxLog - ON_SUBSCRIBE(reactor.core.publisher.FluxArray$ArraySubscription@35bbe5e8) 01:37:18.681 [main] INFO reactor.core.publisher.FluxLog - REQUEST(unbounded) 01:37:18.682 [main] INFO reactor.core.publisher.FluxLog - ON_NEXT(red) RED 01:37:18.682 [main] INFO reactor.core.publisher.FluxLog - ON_NEXT(white) WHITE 01:37:18.682 [main] INFO reactor.core.publisher.FluxLog - ON_NEXT(blue) BLUE 01:37:18.682 [main] INFO reactor.core.publisher.FluxLog - ON_COMPLETE() ... 17:26:15.184 [main] INFO reactor.Flux.SubscribeOn.1 - request(unbounded) 17:26:15.189 [parallel-1] INFO reactor.Flux.SubscribeOn.1 - onNext(red) RED 17:26:15.189 [parallel-1] INFO reactor.Flux.SubscribeOn.1 - onNext(white) WHITE 17:26:15.189 [parallel-1] INFO reactor.Flux.SubscribeOn.1 - onNext(blue) BLUE 17:26:15.190 [parallel-1] INFO reactor.Flux.SubscribeOn.1 - onComplete()
  7. 7. COMPLICATED EXAMPLE@Document class Person { @Id String id; String name; } interface PersonRepository extends MongoRepository<Person, String> { @Query("{}") Stream<Person> all(); CompletableFuture<Person> findById(String id); } @Controller class PersonController { @Autowired PersonRepository personRepository; @GetMapping("/person") public Flux<Person> all(){ return Flux.fromStream( personRepository.all() ); } @GetMapping("/person/{id}") public Mono<Person> byId(@PathVariable String userId){ return Optional .ofNullable(userId) .map(id -> personRepository.findById(id)) .map(person-> Mono.fromFuture(person)) .orElseThrow(() -> new IllegalStateException("error - null id")) ; } }
  8. 8. UNDER THE HOOD Thread HTTP Request Thread HTTP Request 100 . . . @GetMapping("/person") List<Person> get(){ List<Person> result = db.longOperation(); return Response.ok(result); } HTTP HTTP HTTPHTTP HTTP < 100 @GetMapping("/person") public Flux<Person> all(){ return Flux.fromStream( personRepository.all() ); }
  9. 9. COMMON INTERVIEW MISTAKE • ASYNC REQUEST AS AN ANSWER FOR LONG REQUESTS (WRONG) JavaScript queries process Long Running server Display results • PULLING OR PUSHING (RIGHT) Client query Pull status of Job Display Result Server Render Job ID Track Status of Job
  10. 10. DO IT IN REACTIVE WAY @RequestMapping(value = "/report/{userId}", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.OK) public void longReport(@PathVariable String userId){ Mono.just(userId) .subscribeOn(Schedulers.parallel()) // MOST IMPORTANT LINE .log() .subscribe( personRepository::longOperation, websocketRegistry::notifyError, //use WebSockets to report error websocketRegistry::notifySuccess //use WebSockets to report success ); ; //here we return to client status OK }
  11. 11. {FINALIZE} • REACTIVE REVOLUTIONIZE MULTITHREADING BY EXPOSING GOOD DESIGN PATTERNS; • SPRING PUTS ALL TOGETHER; • CHANGE YOUR MIND TO BE REACTIVE. • ANY QUESTIONS?

×