I have to make a call to an API but not wait for its result. I have a stream object. Here's what I am doing:
Mono.just(stream).mergeWith(makeCall()).next().subscribe(...);
makeCall() takes some time, so what I thought is that next() would give me the stream object and it would be propogated down the stream.
What's happening instead is that next() cancels the subscription after consuming `stream. Hence, no call takes place.
Is there a proper way to make a fire-and-forget call?
Related
I have a service that I want to hand out a Subject (although it could be typed as an observable) as the result of a method call. This is straightforward, but what I really want is to be able to "detect" when its unsubscribe method is called (or since it could technically be handed out more than once to multiple subscribers, when its subscription count falls to zero). Is this possible?
If you take a look at the source code to a behavior subject
https://github.com/ReactiveX/rxjs/blob/master/src/internal/BehaviorSubject.ts
you will see how to extend a subject. You could do the same thing to create your own kind of subject that instead of taking a start value it takes a callback to be run on unsubscribe that passes in the observer count. You would need to return a custom subscription object as unsubscribe is done from the subscription.
I'm writing a slack bot with Go and Aws Lambda. Slack requires for the bot to reply within 3 seconds. However, sometimes I can't make it reply that fast, cuz it's "talking" to other serverless applications for requesting some data or dispatching tasks. I have never worked with goroutines before, but I was hoping that I could implement something like this:
Lambda receives a request
The bot creates a goroutine that will process this request and act accordingly on it
The handler doesn't wait for all these actions to complete but replies right away with 200.
Lambda continues to run until goroutine is finished.
I'm not sure if that's even possible.
I've read about sync.WaitGroup, but I'm not sure how to incorporate it together with main function. Should I use it inside the handler? But I need to return response and that's not a function that I can wrap into a goroutine.
Ideally, I would like for handler to reply right away and then process goroutine in the background.
Don't try to do anything in your lambda handler after the request finishes.
A more reliable approach:
Accept the call and record whatever input data is needed.
Put the data in SQS
Respond with HTTP 200
Another (SQS triggered) function does the processing and if needed, calls Slack back on recorded response_url
The Kotlin code below successfully connects to a Spring WebFlux server, sends a message and prints each message sent via the stream that is returned.
fun main(args: Array<String>) {
val uri = URI("ws://localhost:8080/myservice")
val client = ReactorNettyWebSocketClient()
val input = Flux.just(readMsg())
client.execute(uri) { session ->
session.send(input.map(session::textMessage))
.thenMany(
session.receive()
.map(WebSocketMessage::getPayloadAsText)
.doOnNext(::println) // want to replace this call
.then()
).then()
}.block()
}
In previous experience with Reactive programming I have always used subscribe or subscribeWith where the call to doOnNext occurs. However it will not work in this case. I understand that this is because neither returns the reactive stream in use - subscribe returns a Disposable and subscribeWith returns the Subscriber it received as a parameter.
My question is whether invoking doOnNext is really the correct way to add a handler to process incoming messages?
Most Spring 5 tutorials show code which either calls this or log, but some use subscribeWith(output).then() without specifying what output should be. I cannot see how the latter would even compile.
subscribe and subscribeWith should always be used right at the end of a chain of operators, not as intermediate operators.
Simon already provided the answer but I'll add some extra context.
When composing asynchronous logic with Reactor (and ReactiveX patterns) you build an end-to-end chain of processing steps, which includes not only the logic of the WebSocketHandler itself but also that of the underlying WebSocket framework code responsible for sending and receiving messages to and from the socket. It's very important for the entire chain to be connected together, so that at runtime "signals" will flow through it (onNext, onError, or onComplete) from start to end and communicate the final result, i.e where you have the .block() at the end.
In the case of WebSocket this looks a little daunting because you're essentially combining two or more streams into one. You can't just subscribe to one of those streams (e.g. for inbound messages) because that prevents composing a unified processing stream, and signals will not flow through to the end where the final outcome is expected.
The other side of this is that subscribe() triggers consumption on a stream whereas what you really want is to keep composing asynchronous logic in deferred mode, i.e. declaring all that will happen when data materializes. This is another reason why composing a single unified chain is important. So it can be triggered after it is fully declared.
In short the main difference with the imperative WebSocketHandler for the Servlet world, is that instead of it being a handler for individual messages, this is a handler for composing the complete streams. Here the handling of an individual message is just one step of the overall processing chain. So the only place to subscribe is at the very end, where .block() is, in order to kick off processing.
BTW since this question was first posted a few months ago, the documentation has been improved to provide more guidance on how to implement a WebSocketHandler.
I have some doubt in Asynchronous and synchronous terms in ajax.
How Asynchronous process will work?
Can you please let us know about this terms?
Synchronous ( async: false ) – Script stops and waits for the server to send back a reply before continuing.
Asynchronous ( async: true ) – Async requests occur on a background thread, meaning that the UI is not going to be blocked while the request is processing.
Why AJAX has called Asynchronous? Can you please describe any one
please?
asynchronous is the best because the client and the server run independently of each other for the duration of the function call.
During a normal function call, you make the call, and the calling function doesn't get to execute again until the function call finishes and returns. The caller and the callee are always synchronized.
During an asynchronous function call, you make the call, and then control returns immediately to the caller. The callee then returns a value some indeterminate amount of time later. That "indeterminate amount of time" means the caller and callee are no longer synchronized, so it's asynchronous.
Meanwhile you can make multiple request if you set async:true because control returns immediately, it will not wait like synchronous call till it receives response from server, here is picture which give clear idea.
So the case is this. Suppose somewhere I am filling a Collection. Each time an element is added, an IObservable calls OnNext for its subscribers.
Now, there will be a point where the collection will be filled. (I was reading something and I finished reading .. whatever). At that point, OnComplete() is called on the subscribers.
The user, however, won't observe this method. He will rather call an async method that he will await for ... he doesn't care much about the things he read, he just cares that he finished reading.
So basically, I want, from an IObservable, a Task that returns when the IObservable calls OnComplete() to its subscribers. I specifically want the user not to use an observer, but just to be happy with knowing that whatever happens after his await call will happen after the collection is filled.
Maybe the ToTask() method does the trick? I can't really tell by the documentation.
If you are using Rx 2.0 or later you can await IObservable which returns the last item in the observable. I.e. after the observable has completed.
var lastItem = await myObservable;
This is possible because in Rx 2.0 a GetAwaiter extension method on IObservable was added making it possible to await observables. There are also some handy extension methods that allow you to specify which element you want to await.
There is a nice blog about it here.