Don’t use Reactive Streams in Java 9+ - Jacek Kunicki

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
thank you so I don't usually take selfies during my talks but this is a special so let me just take one please wave your hand to show that you're here okay that's it my name is Yasukuni GE I work at software mill we're a software consultancy we write code like everyone does probably most of you there are however two special things about us that make us unique the first one is that we are a fully remote company so we don't have an office and the second one is that we have a completely flat structure we have a full internal transparency including the financial one so if you are eager to learn how it can work or how it cannot work please feel free to catch me after the talk and today we will talk about using or not using creative streams in Java 9 plus actually I'm going to tell you how to use them properly and how not to use them so what you should be doing what you should not be doing with reactive streams in Java 9 plus let's start with a quick recap what stream processing in general is and what reactive streams actually are so in a stream processing environment you start with some source of your data you can call it a producer you have some kind of destination for your data which you can call a consumer and you have a number of intermediate processing stages in the middle so the stages that do something with your data and typically you have data flowing from from left to right so from the consumer through the stages to the from the producer to the stages to the consumer now if you imagine what can go wrong in such an architecture there is one one situation when when the producing side so when the producer is faster than the consumer because then we need we have some excessive data that so we need to deal with somehow and there of course different different strategies to deal with this excessive data for example the like the simplest one that you can think of is just dropping the excessive data it is actually not something very uncommon because if you look for example at the networking hardware this is something that actually happens there so if you have some excessive data that are that is not able to be handled then it is just dropped another approach is for example to block so the the slower consumer can can just block and not allow the faster consumer to send data to it and then the producer is basically blocked the consumer does his job and only when it's done next data the next data can be processed another strategy to delete excessive data is for example to buffer it but buffers as most most of the things inside the computer are limited so if you have really a lot of data coming from a fast producer and you have a slow consumer that is buffering the data then there is a danger that the buffer is going to overflow so you're going to get an out of memory error or something like that so the last approach that I'm going to talk about in some more detail and which is actually used in the in reactive streams is called back pressure and back pressure is basically a way for for the for a slower consumer to slow down the producer so you can think of back pressure as as another kind of data that is flowing in the opposite direction so it's it's it's going upwards in the stream and it's basically a way for for a consumer to slow down the producer so so to tell the producer that it's you are too fast I'm not able to accept that much data now there's a small digression about naming because this is like a general general naming for for stream processing pipelines in in Java 9 the interfaces have their own names so the producer is called the publisher the consumer is called the subscriber and this processing stages are called processors so this what what you can see in the slide is like the general stream processing pipeline but this is not yet reactive so what do we need to do to make it reactive well first of all it needs to be a synchronous so for example when when I spoke about ways to handle excessive data I mentioned blocking so blocking really is not the way to go in a reactive in a reactive stream because you need to you need to act as synchronously also the backpressure so the mechanism for a slow consumer to tell the producer that it's too fast and to slow it down needs to be non blocking so it's also that the data cannot get the data flow cannot be blocking and the backpressure flow cannot be either this is important because in in a reactive setting so in a non blocking setting you should really be able to reuse threads whenever it's possible and doing doing non blocking back pressure so the non blocking communication to upstream should also should also make the computer able the tablet processor able to reuse the threads whenever it's possible now another important thing in RIA in a reactive stream is that the slower consumers are somehow represented in a domain model and I have two examples here the first one is a Twitter API so if you if the Twitter a Twitter exposes an API which lets you like connect to a stream of tweets and then it allocates a buffer that from which you can consume and normally when you when you consume with a good enough speed from the buffer you're just getting the data but if if the Twitter endpoint detects that you are performing too slow it actually can put some special message inside the buffer that tells you that hey you are doing too slow if you don't speed up in some some amount of time then I'm going to drop the connection so this is this is something something new you may you may think of it like something new because you don't just get the data inside the stream but you also have some some signals that are telling you that you need to speed up for example here another example comes from the ARCA streams API and it's this is a state so one of the intermediates building blocks in a stream this stage is called conflate and conflate what what it basically does it's when it detects that the down stream is slower it aggregates the data instead of just sending it downstream and only when when the downstream becomes fast enough it starts it emits some kind of aggregated data and now this is some very nothing too original because well it's just buffering but the important thing here is that actually this is somehow included in the domain model so in the you have a processing stage built-in innaka streams that is aware of the fact that the downstream can be slower and it's able somehow to deal with it now starting from Java 9 dar some new interfaces which are in the Java util concurrent flow class there are actually four of them I'm now going to quickly cover what they are here for and what they look like so the first one is a publisher and publisher is it's pretty straightforward basically it produces elements of some given type T and it has a possibility to send them to subscribers that are that are then going to consume those elements and it exposes a single method called subscribe which subscribers are going are using to connect to the producer to the publisher so we have a publisher this is the like beginning of our pipeline then at the end we have the subscriber so subscriber basically consumes element from the publisher it needs to call subscribe on the publisher in order to receive for example a continuation of the subscription I will cover subscription what subscription is later so it it can receive an unsubscribe call back then it can receive data we are we are the on next call back and it also exposes methods for receiving some other signals like honor or for signaling errors and uncomplete for signaling completion so we covered the publisher we covered the subscribers of the variants of our pipeline now we have a subscription a subscription is actually nothing more than representation of a link between a publisher and the subscriber and it allows for two things it allows for back pressuring so here here is the place where the actually most important part of reactive streams the backpressure comes into play so subscription is that is the link between a publisher and the subscriber and it's it allows among others for back pressuring with the request method it also allows for council links or or timing terminating the flow with a council method now the last interface that we have is a processor and processor is something really simple because it's basically something that is bought a publisher and the subscriber so it has it has two ends publisher had a single end that emitted the data subscriber had a single and it received the data and then you have a processor that has two ends and it's able both to receive and to to emit the data so now in a typical scenario what is called first is the SUBSCRIBE method on a publisher because we have a subscriber that connects to the publisher and then it can receive the unsubscribe call back as I mentioned then after it after receiving the subscription it can receive an arbitrary number of on next callbacks with data and then it's either completed successfully or with an error so I assume everyone here is a developer probably so when you see such simple interfaces I would assume that the first thing you think of is implementing them so let's actually try to do it and try to implement those interfaces so what we are going to do is try to implement a simple publisher for data is going to hold an iterator of integers and then when when a subscriber connects is going to emit the iterator until it's exhausted so now in a in a very naive approach what you could actually try to do as the very as the first very simple implementation is just to take the iterator take all the remaining elements and just send them to the subscriber and then perhaps you also want to signal completion so when the iterator is exhausted you want to tell the subscriber that we are done so you're going to call on complete so let's see whether it can act it can work at all to do this we need a main method that is actually going to run it we're going to create a new simple publisher with ten elements to emit down stream and we're going to call subscribe because we need to provide a subscriber that is going to consume the data and we're going to create an anonymous instance of a subscriber and implement a part like part of its metals so I'm not going to implement on subscribe' yet I'm going to start with wit on next and those implementation is going to be very very very simple so here we're just going to print out the elements that we received the same is going to happen with any errors that we receive so we're just going to print them out and then on on completion we are also going to just write to standard output an information that it has been completed so we just print complete so this is a very simple implementation of a subscriber that is connected to our very simple publisher that just ties the iterator iterates over it and sends all the data downstream let's run it and see if it works so this is an odd machine so you need to be patient yeah well we have ten elements that have been emitted and received by the subscriber we have the completion signal that has been received so looks good but you may wonder whether it's that simple to implement a publisher yourself a reactive one and it's not now when you when you want to implement something that is reactive so something that is going to behave correctly when connected to other reactive components you actually have like a huge huge number of requirements that it's it's it needs to stick to and actually those all those requirements are covered in something that is called a TCK or technology compatibility kit for reactive streams and the TCK describes all the principles that the reactive components need to follow and it also gives you some some rest some already prepared tests that you can run against against your implementation and this is what we are going to do now so we have some simple publisher test that uses the flow publisher verification which is a base class from the TCK that actually is going to use an instance of our single publisher and run all the tests for a reactive publisher against our implementation so let's see what's going to happen and now you can see that this doesn't really look good so we have a single path test which may be around them one but we have 15 of them failed so as you may have expected our implementation is far from perfect so well it seems to do its job but it's really not a reactive one so let's not try to fix it a bit to see to see what the potential problems are and and what we can do about them so for example we'll start with the one point one zero nine error which says that an unsubscribe callback must be issued when a non-null subscriber is connected so this is when you may remember from the slides that a subscriber after connecting to a publisher needs to receive an unsubscribe callback and we're actually not doing it that's why there are the test files so let's try to implement so getting back to our publisher we are not going to need the main method anymore let's just delete this code and now we are expected to call on subscribe I'm a subscriber so let's do it and here you can already see that what we need here is a subscription as you may remember the subscription acts as a link between the publisher and the subscriber so we need we need to have one so we are doing simple stuff here so let's call it simple subscription and what we are actually going to do is pass the subscriber instance there because we want to move all the communication between between the publisher and the and the subscriber inside the subscription so now it's going to be the subscription that will manage all the communications of the backpressure and other things so now we're going to create inner an inner class for our subscription we have the instance of a subscriber we want to store it as a field in our class and then we also need to implement the methods that are required by the subscription interface as you may remember there are two of them first one is request for handling for dealing with back pressure and then handling the request from downstream and the other one is cancel so let's start with with implementing request so in requests we are receiving a number that tells us how many how many elements the downstream ones and our goal here is to send no more than an element to the downstream so let's just do it as simple as it's possible so I'm just going to use a for loop with a variable called demand I'm going to initialize with with an then the condition is going to be that the demand is greater than zero and also that the iterator has some more elements to provide because if the iterator is exhausted we actually don't have anything to send downstream so I'm going to that iterator has next here and I'm going to decrease the demand and now inside the for loop what we are going to do is just take the subscriber you call the on next callback to send the next element to the subscriber and the next element is going to be the next element taken from the iterator so this way we are we are just sending an element to the downstream using the subscriber on next callback and now when we are done sending this n elements it would be good to check whether the iterator has any more elements because if it has not it will be a good idea to send a completion signal to the subscriber to signal that we are done basically so here we'll say if not iterator has next we are going to say subscriber on complete so once again what we do here is basically send an element's downstream then check whether the iterator has any more elements if it doesn't we could we complete we send the completion signal to the subscriber so let's run the test once again and see what happens oh sorry yeah so actually actually there is someone long-running test there so I'm going to stop the previous run and just run it once again and you may remember that we are looking at 109 which required us to issue an unsub unsubscribe call back for a new now subscriber and this is what actually happened so there are still some failed tests but at least we were able to fix something so let's not try to fix some more stuff for example if we look at 3:09 it says that when a negative number of elements is depressed that we need to signal an error with an illegal argument exception or the same should happen when there is zero elements so we basically should handle an edge case where n in our request is less or equal to zero this sounds simple so let's try to do it so here I'm just going to put a simple check if n is less than equal to zero and then we need to signal an illegal argument exception but it is important that we are not just allowed to throw an exception here because although all the error communication also needs to be handled via callbacks so instead of just throwing the exception we need to use the error callback from the subscriber to pass the exception this way so new illegal argument exception then that's pretty much it so what we did now is just check the edge case where zero or less elements were requested and then you can see that 309 is passing so we we fixed another error well we're doing really good so I'm going to try to fix another one and this is actually or even two of them so if you look at 105 it says that we need to signal completion when the when is to in terminates and when you look at 107 it says that one that once we complete we should not be sending any more elements so those two errors suggest that we we are doing something wrong with with signaling termination of our stream which actually means that we are missing some internal state of our of our subscription that would be able to tell whether it has been it has been terminated or not because you need to remember that this is a multi-threaded environment so it to behave correctly even in such a setting so to hold this state we're going to use an atomic boolean and call it terminated terminated and initialize it with false so this makes sense initially we're not terminated and now the like first most obvious place to set the terminated value is in the console method so whenever we receive a canceled signal we need we want to set the terminated lock to true to indicate that we are done and there are two more places where we need to check it so the first one is before sending an element downstream so apart from checking whether the iterator has any more elements available we also need to check whether we are not terminated so we need to add another condition here not terminated don't get so this is an additional check because if we have been terminated we don't really want to send anything downstream and the second error was about signaling completion too many times so what we want to do is also check the terminate if lock here because once we signaled completion to the subscriber we don't want to it annum anymore so here theoretically I just using get here would be enough but if you think about it carefully it turns out that apart from taking the value from off from terminated we would also need to set it to true so to actually indicate that we are terminated because we are sending the completion signal so if we decide to set to send the completion signal by subscriber uncomplete we should also set the flag to truth to indicate that we are terminated and actually atomic boolean offers a method that lets us do it atomically so we can read the value and then set it to something else and that's what we'll be using here so we'll be using get and set with with value with the value of true and of course it's not terminated getting set here so what does if it takes the value from the atomic boolean check whether it's false and what whatever the value was it's setting it to true to signal termination so once again what we did here was to introduce some internal state called terminated anatomic boolean that basically holds the information whether we're done or not and we are using it in several places first when we receive a canceled signal in our subscription then we set it to true and also we check the flag before sending anything downstream or signaling completion let's see if it helped so now it's much better I would say because we're we were left with only two filing tests and actually all the rest is passing so let's not focus on on those two they are failing so one of them is about unbounded recursion and the second one is about handling long max value so handling clunk max value is basically something about an infinite demand that we are receiving so let's have a look at those so the first one was an unbounded recursion and unbounded recursion can happen when we have a synchronous implementation of our of our subscription and that's what we actually did because we didn't start and threats we didn't do the request handling in in an asynchronous way all we did was synchronous and actually what we did in our request request method was calling on the next on the on the subscriber and then it turns out that usually a subscriber when it receives on next so it receives the next element then it processes it and what it does next well it requests new elements so it's going to call request again and then we are getting into a kind of infinite loop so in the request we are calling on next but then on next in turn is going to call request again and this is the unbounded recursion this is only a problem in an asynchronous implementation so this is like a hint that when you are creating your own publisher for example you shouldn't be doing it synchronously there should be something a synchronous inside in order - not to get into this kind of problems but then if you go with an a synchronous implementation there are some other problems that you may face and they are for example related to handling the infinite demand so basically the thing that you just saw and the problem is that for example if you're allocating threads for for handling for handling your request calls and and you received and the end is going to be long Max values or something very big then you're certainly going to like run out of threads because well you can allocate a number of threads on a on a machine but certainly not long max value threads so this is going to blow out so then you may think about for example accumulating the demand somehow storing it at a long value but then you may you may have a problem of of just of a number overflow because if you receive Torito requests calls with both both with a long Max value as the parameter then well you you're not going to be able just to store it because it's going to blow out as well so actually the takeaway here from from this short demo and this my like attempts to fix the errors that we are getting from the TCK is that you really shouldn't be implementing those interfaces yourself however however simple they may seem is not really a good idea to just go and implement them of course if you are implementing a library you can be doing it because that's actually what the interfaces are there for so the goal of the interfaces the what what they are here for in the JDK is an SPI which stands for a service provider interface and the service provider interface is basically a unification liar for different implementations so for different libraries that are going to behave in a reactive fashion so if you are implementing a library go for it but just don't don't just try to do to implement them yourselves rather use something that is that is thoroughly tested now their idea and the reason why the why a unification layer is needed is that for example there are already some some streaming abstractions in the JDK itself so when you look at them you can just start for example by the file i/o so you have an input stream and an output stream which even even the name suggests our something about about streaming you have and many more things like an iterator well it's it may it's not a stream really but it also exposes something like a streaming behavior because you don't process everything at once but just send an element by element you have the new IO with channels in the most recent surplus pacification I think it's three point one you also have read and write listeners which also behave in a synchronous fashions and they can resemble streaming in a way you have Java sequel result set which usually is backed by a cursor in a database so this is also something that you can think of as a stream because it's and it sends chunks of data and not all the data at once well you have streams from Java 8 so this is something that certainly exposes a streaming behavior and in Java 9 you have this Java util concurrent flow and all the interfaces that we have just covered now the problem is that like all of this abstraction exposes a different API and it's really really hard to connect them together and if you think about how how as publisher connects to a subscriber with a single subscribe method this is not what you can do yet so you are not able to read files and then transfer data between the files or between a file and a database for example and actually this single call that you have here is very important because well it's what it does by connecting the publisher to a subscriber is to establish a link that is responsible for backpressure so for handling different speeds of the publisher in the subscriber and it also handles handles cancellation handles termination and deals with error handling so this is a single call that is that is really important and it would be nice to have something like that in the JDK and then using it be able to connect all the all the different streaming abstractions but that's at fault unfortunately not what we have in the JDK at the moment so let's let's have a quick look at I would say nice to have so what what it will do what it will be nice to have in the JDK to be able to play with this swimming obstructions in a reactive way so the first thing we will be happy to have is a some some minimum operation set on the streams so at the moment as you as you sold are only those four interfaces and there is actually no implementation well there is one actually it it's called the submission publisher and this is like a demo complaint in the JDK how you can use it but the submission publisher is synchronous and as you saw previously you when when we run the TCK test against our implementation which was synchronous as well it didn't really work or well so the submission publisher is also not like best implementation to use because it's synchronous so it doesn't really it's not going to play well with other a synchronous reactive components what we are lacking for example are some basic operations on the stream itself so if you if you're familiar with other streaming's reactive switch implementations like project reactor Eric's Java or ARCA strings there's a number of for stream Combinator's or whatever you call them so those are metals like filter or map or something else that you can just run on your stream and do some transformations and actually in the JDK you are missing even those so there is there is no no filter no map on the stream you just have the interfaces and actually there is an initiative from live band called reactive streams utils and it is goal is to provide a provocateur a cable implementation of the of some operators on the stream so the idea is that the basic operations like filter or map that I just covered should be there in the daily case so they should be provided out-of-the-box but then it would be nice to be able to choose your your the implementation you want to use for the more advanced stuff so for the most at more advanced combinators and this would this would this work by setting a proper system parameter but certainly when it comes to like things in our in the Java echo system there is also some politics and here as in some other places we have a like fight between spring and Java EE or Jakarta II so the the yellow and blue logo here is decart IAE so that it which is the new Java EE and well if you think of spring for example an its support for reactive well spring is already using project reactors so actually people who are using spring and who are responsible for like the developing spring I'm not really interested in including all the reactive stuff in the jdk because well they are using projects reactors so why would they care about about using something else on the other hand there's a lot of companies that are actually using java ee or jakarta ii and they would be happy to have all those all those even simple implementations inside the jdk because they want to use stick to the to the java api and not use something like spring so looking like further into the future in a possible future because no one sex is going to happen let's see other nice to have so for example if you think about HTTP and making the HT because in a reactive way well there is a sink serval io since third service 3.1 and actually there is an HTTP client in jdk 9 that is able to deal with reactive interfaces so for example it exposes a post method that takes a publisher and then it's it's able to deal with the data from the publisher so for example if if the servlet io exposed also expose the publisher to like to using the data contained in the request which it doesn't do now because it has some has some regions right listeners but it doesn't have the reactive interfaces then you feel if you think about the task of uploading a file this would become something very simple like using the post method that accepts a publisher and using the like hypothetical publisher from the from the service request so here the rig request get publisher method is something that is not there but it would be nice to have something like that because then you would you would be able to set up a file upload with a single line and it will all things like back pressure error handling signalling completion will be dealt with under the hood and your responsibility would only be to connect those two with this single method another place where we could see some improvement is for example database access so there is something called a DBA which is called asynchronous database access API and it's actually going to be a part of the JDK this is something like asynchronous a JDBC but it's not not a wrapper for JDBC it's something they are implementing from scratch and at the beginning they try to incorporate the reactive interfaces there as well but unfortunately it turned out that implementing them as you already seen is not trivial so they at the moment they have dropped support for reactive for reactive implementations for the reactive interfaces inside a DBA so there is going to be some asynchronous database connectivity but really without the reactive interfaces there are of course some vendor specific a synchronous drivers some of them support the reactive interfaces but still they are vendor specific they are not the part of the JDK so they are not something that you have available out of the box when you just download the JDK and have it in place so when you think of of how used API and for example if if if you fed a result leaf from a database then you receive a list of a list of objects but what if you were able to do something like this so like create a JPA query and then instead of getting a result list get a publisher which instead of giving you a list will give you a publisher of data and then you we'll be able to consume the data from the database not from a list but actually from from something that is reactive this is of course something that is not there yet in the JB API and just as a reminder those are like nice to have so things that would be would be good to to exist in the JDK and so that would be able to connect everything with the with the reactive way there is certainly more so for example you can think of a reactive file IO 4 if you think for example about transferring data from one file to another so today if you wanted to do it with the input and output stream you need to allocate a buffer yourself and then like deal with reading data to the buffer then writing it to a file but if you were if the file i/o is supported reactive streams you would once again be able to do it with with the SUBSCRIBE method with a single one that would deal with the backpressure and all the good things JMS is another example where this could be useful because this is like something that you can also think of as a streaming pipeline actually by sending the messages with slower and faster parties WebSockets is another example so this is also about sending chunks of data for example iws and actually at AWS is working on supporting the the reactive interfaces but it turns out that they are using them internally so so the API they they are exposing is not it's not giving you access to the to the reactive interfaces but they are using it instead so this is well this is partially good but it would be perfect if they just expose the interfaces and then you would for example have a subscriber from LW s 2 which would be able to pipe your your data to upload it to s3 for example there is also project alpaca from light band if you haven't heard of it it's basically a set of connectors for akka streams so for one of the academically streams implementations alpaca is something like like Apache camo but but it works in a reactive in a non blocking quite camel is blocking most of the times alpaca is not so this is a completely different model so you could say that it's there but again we are thinking about things that it would be nice to have in the JDK so this is still an external library but at least you have some reactive connectors to the outside world so since there is really not much to show about integrating different libraries because the the examples you saw are really about something that may be there in the future but III wanted to do some some kind of demo for for the actual for the spi parts of order for the unification layer for different implementations of reactive streams so what I'm going to show now is a very simple pipeline that is going to use three different implementations of reactive streams so we are going to start with a publisher that will be constructed with project reactors flux then we are going to use our cast rims in the middle to do some processing and eventually we're going to use our graph as a subscriber so those are like three implementations of reactive stream reactive streams each of them like having its own world but actually it turns out that using the new interfaces that are there in the JDK we'll be able to connect them and make them work together so if you look at this example code well what we have here is a is a publisher from project reactor then we have a process or from ARCA streams so this is this one then we are using using subscribe to connect those two so this once again makes the like that the process or read data from the publisher and eventually we're using the flowable from Eric's java to attach to the ARCA stream processor and to read the data and then to just just write it to standard output now if you if you look at the implementations you see that the interfaces here are actually the unified ones so this is where the where the reactive streams interface is from Java 9 coming to play because we are we are using different implementations but the interfaces on top are the same and if you look at the actual implementation you can see that this is indeed flux so a project reactor source of numbers here because what flux interval does it basically emits a number every every one second here and then you need to use some glue code which you can see here to be able to convert the project reactor interfaces to the reactive strings ones because as I said like every implementation has its own world but now since the reactive interface are in the JDK have a way to like lift the the for example here project flux representation to the Java nine interfaces and something similar happens in the processor so here you can see that we are indeed using the flow which is which is the ARCA stream DSL for the order for a processor for so foreign a component that is doing some transformations for the data and that does is negating the longer values it's going to receive so because we are using map from I - - I here and once again we need to use some glue code here so we had the ARCA streams API as a flow and then we want to lift it - that the reactive interfaces using Java flow support here and here you can actually see some some nuances that show that the implementations of reactive streams work work differently so for example if you wanted to use the glue code from from project reactor it just called publisher to flow publisher and it's there but in Arcis trims you need to use something like a materializer and the reason is that akka streams uses a bit different approach to like constructing the entire pipeline because it separates the recipe for processing data from the actual runtime and the materializer you see here is the is the runtime that you did that is separate from the definition of the stream and you are using it to actually run the stream so that's and you need to be explicit about creating it so in project reactor it's somehow hidden under the hood so you don't know anything about the runtime but in our cast rims you actually need to create the runtime you serve as the materializer okay so let's see whether it works it takes some time to start and then you can see zero which is not negated and the other numbers are negated so you can see that we were actually able to connect different implementations of reactive streams using the using the interfaces it was again this is the actual goal of of the interfaces being there in JDK so it's it's like a unification layer for different different implementations different libraries that implement the concepts of reactive streams you saw some error order this is due to the fact that we are not handling termination gracefully but this was just a simple example so let's just forget about it so to wrap it up as you have seen this is what we have in the JDK is certainly not a full reactive streams implementation because apart from the from the interfaces and apart from the single synchronous implementation the submission publisher we don't really have anything more like even simple stream combinators like filter or mod it is rather an SPI so a service provider interface that allows different different libraries that implement reactive streams to work work gracefully with each other so that they are basically able to connect and to interchange the data in a reactive fashion you have also seen that implementing those interfaces yourself it's really not trivial so what we were trying to do here was implementing a publisher so publisher when you think of complexity is somewhere in the middle so cons like that the subscribers are the are order like easiest to implement the publishers are somewhere in the middle and processors are the most most difficult to implement so you need to remember about it and whenever you think about implementing it yourself because it's not that you are it's not that forbidden to do it but it's rather you should think carefully whether if should another be using some some reading implementation that what it was tested thoroughly but if you decide to implement it yourself be sure to use the TC K and once again TC K is basically a set of rules that tells you how the components should be implemented so that they can work nicely one with one with another so that all the the reactive behavior is preserved and it also gives you the the tests of the test the testing part is the the most important one that you really should be using it while doing your own implementation because as you as you saw in the live coding at the beginning this is really not not trivial to do it and we when you start with with doing something in a very simple way and with a synchronous way it's a lot of things can go wrong and those are things that you really wouldn't think of if you didn't have the the TCK and the tests at hand so be sure to at least have a look at the TCK there are some resources if you want to dive deeper after this talk the first one is the pluggable runtime so the idea that you have some basic operations built in and then you have a runtime that you can use to give you all the other all the other Combinator's and this is reactive streams you tooth from light band there is a TCK which like it's I could dress it infinitely that is really important to have a look at it if you want to implement something some of the interfaces yourself there is a block about a DBA which as I said unfortunately probably won't be supporting the reactive interfaces but if you are like into reading about asynchronous database connectivity anyway have a look at it and there is a nice nice blog series about advanced reactive java it also covers some of the things i covered here like trying to correctly implement the interfaces yourself normally when you when you google for reactive in java 9 you have a number of blog post that actually tell you how to the try there are four simple interfaces let's implement them they are so showing some simple implementations but they are really not mentioning the TC k so they are they are missing the crucial part which is which is like the all the complexity that is hidden behind reactive streams and in this blog post series in advanced reactive java you have you have the TC k covered and you have the complexities cover so this is actually a nice place to look at as well that's all I had if you have any questions feel free to ask now just wait for the mic otherwise I'm here today until the end of the today's conference so you feel free to catch me yeah I see a question up there but I'm not sure they will be able to okay so as long as I can hear the question was about why are there is the reactive approach in streaming better than typical like blocking approach so why why back pressure why are synchronous and the answer is it was somewhere on the slides that basically it's all about reusing the reason the resources so if you if you work in in a synchronous environment in the blocking one the threads are blocked basically and the core idea behind reactive is to like release the resources whenever you don't actually need them so not to block them but but give them back so that something god can use them and actually that's so this is about the uh synchronicity and actually and back pressure is actually also about about limited resources because if when I spoke about ways to deal with access data well there are some approaches that are not the best you can imagine like like dropping or or blocking or buffering the data because this can lead to some problems and actually back what back pressure allows you to do is when you think of an like integration architecture when you have different systems that work at different speeds and back pressure is like a built in concept that lets you deal with those different speeds gracefully without worrying about running out of memory or running out of other resources there is one more question here sorry I can't hear you I but here's a mic and I think there should be someone to pass it but let's just can we have the the audience mic please okay so you can ask here and I will repeat the so the question is about comparing the the streams in Java and reactive streams with Kotlin coroutines and actually the honest answers I don't know because like I've heard about coroutines in Kotlin but I know don't know the implementation details so I don't want to give you an answer because it would probably be wrong me wrong sorry for that so the question is whether the integration demo is going to pass the TCK I think it would because I really wasn't using any code of my own I will I was using like their implementations like project reactor or examine data streams and as far as I know they are tested against did CK so I didn't I didn't use any component that I wrote myself like the publisher so I'm I'm pretty sure it would okay one more question I'm going back to the stage Oh hear me okay a simple one actually is any one of those nice-to-haves that you mentioned during the talk actually being developed as part of future JD case or the Oracle basically just develop the interfaces and they sort of abandoned the project so this is really a good question and actually I'm not aware about an initiative of implementing it so this is like that the moment we are in now it's like a decision moment and it's really like the the future of the of the JDK is being decided now because if actually I don't think they are implementing it so if no one else develops it as a path as part of open JDK for example it's really not going to be there so if you are for example willing to have something like that feel free to try to implement it but as you so it may not be simple so even Oracle dropped support for the reactive stuff in the asynchronous database connector so but unfortunately well the I don't want to give any personal opinions here but this is like well you don't see anyone implementing that it would be nice to have but if no-one implements it it's not going to be there so that's pretty much it okay so I don't see any other hand so thank you once again time feel free to catch me afterwards [Applause]
Info
Channel: Devoxx
Views: 19,288
Rating: 4.6883116 out of 5
Keywords: DVXPL18
Id: _stAxdjx8qk
Channel Id: undefined
Length: 48min 58sec (2938 seconds)
Published: Tue Jul 17 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.