Since redis is single threaded, making a call like the one below will block until it returns:
redis.hgetall("some_key")
Now say I was to wrap all my calls in Futures, for example if I had to make 100K of these types of calls all at once:
Future.sequence(redis_calls)
Would doing something like this help in terms of performance? Or failure tracking or would it potentially cause a problem if the calls get backed up?
You'll find that the slowest part is getting commands to Redis and reading the results back again, rather than waiting for Redis to carry out the requests.
To avoid this, you can use pipelines to send a bunch of commands at once and receive the results back together.
Related
From what I understand the main q thread monitors it socket descriptors for requests and respond to them.
I want to use a while loop in my main thread that will go on for an indefinite period of time. This would mean, that I will not be able to use hopen on the process port and perform queries.
Is there any way to manually check requests within the while loop.
Thanks.
Are you sure you need to use a while loop? Is there any chance you could, for instance, instead use the timer functionality of KDB+?
This could allow you to run a piece of code periodically instead of looping over it continually. Depending on your use case, this may be more appropriate as it would allow you to repeatedly run a piece of code (e.g. that could be polling something periodically), without using the main thread constantly.
KDB+ is by default single-threaded, which makes it tricky to do what you want to do. There might be something you can do with slave threads.
If you're interested in using timer functionality, but the built-in timer is too limited for your needs, there is a more advanced set of timer functionality available free from AquaQ Analytics (disclaimer: I work for AquaQ). It is distributed as part of the TorQ KDB framework, the specific script you'd be interested in is timer.q, which is documented here. You may be able to use this code without the full TorQ if you like, you may need some of the other "common" code from TorQ to provide functions used within timer.q
I'm wondering if Futures are better to be used in conjunction with Actors only, rather than in a program that does not use Actor. Said differently, is performing asynchronous computation with future something that should better be done within an Actors system?
Here why i'm saying that:
1 -
You perform a computation for which the result, would trigger some action that you may do in another thread.
For instance, i have a long operation to determine the price of something, from my main thread, i decide to launch an asynchronous process for it. In the mean time i could be doing other thing, then when the response is ready/availble or communicated back to me, i go on on that path.
I can see that with actor this is handy, because you can pipe a result to an actor. But with a typical threading model, you can either block or .... ?
2 -
Another issue, let say i need to update the age of a list of participant, by getting some information online. Let assume i just have one future for that task. Isn't closing over the participant list something wrong to do. Multiple thread maybe accessing that participant list at the same time. So making the update within the future would simply be wrong and in that case, we would need java concurrent collection isn't it ?
Maybe i see it the wrong way, future are not meant to do side effect
at all
But in that case, fair enough, no side effect, but we still have the problem of getting a value back from the calling thread, which can only be blocking. I mean let's imagine that, the result, would help the calling thread, to update some data structure. How to do that update asynchronously without closing over that data structure somehow.
I believe the call backs such as OnComplete can be use for
side-effecting (Am it right here?)
still, the call back would have to close over the data structure anyway. Hence i don't see how not using Actor.
PS: I like actors, i'm just trying to understand better the usage of future without actors. I read everywhere, that one should use actor only when necessary that is when state need to be manage. It seems to me that overall, using future, without actor, always involve blocking somewhere down the line, if the result need to be communicated back at some point to the thread that initiated the asynchronous task.
Actors are good when you are dealing with mutable state because they encapsulate the mutable state. and allow only message-based interaction.
You can use Future to execute in a different thread. You don't have to block on a Future because Scala's Future compose. So if you have multiple Futures in your code, you don't have to wait/block for all of them to compete. For example, if your pipeline is completely non-block or asyn (e.g., Play and Spray) you can return a Future back to the client.
Futures are lightweight compared to actors because you don't need a complete actorsystem.
Here is a quote from Martin Odersky that I really like.
There is no silver bullet for all concurrency issues; the right
solution depends on what one needs to achieve. Do you want to define
asynchronous computations that react to events or streams of values?
Or have autonomous, isolated entities communicating via messages? Or
define transactions over a mutable store? Or, maybe the primary
purpose of parallel execution is to increase the performance? For each
of these tasks, there is an abstraction that does the job: futures,
reactive streams, actors, transactional memory, or parallel
collections.
So choose your abstraction based on your use case and needs.
I'm looking into the best way to have my app get notified when a collection is updated in mongo. From everything I read on the interwebs, the standard practice is to use a capped collection with a tailable cursor and here's a snippet from mongodb's docs on tailable cursors.
I notice in there snippet that they have a continuous while loop that never stops. Doesn't this seem like a bad practice? I can't imagine this would perform well when scaling.
Does anyone have any insight as to how this could possibly scale and still be performant? Is there something i'm not understanding?
EDIT
So this is a good example where i see the stream is just open and since the stream is never closed, it just has a listener listening. That makes sense to me i guess.
I'm also looking at this mubsub implementation where they use a setTimeout with 1 second pause.
Aren't these typically bad practices - to leave a stream open or to use a setTimeout like that? Am i just being old school?
I notice in there snippet that they have a continuous while loop that never stops. Doesn't this seem like a bad practice?
Looks like it to me as well, yes.
Does anyone have any insight as to how this could possibly scale and still be performant?
You can set the AwaitData flag and make the more() call blocking for some time - it won't block until data is available though, but it will block for some time. Requires server support (from v. 1.6 or so) That is also what's being done in the node.js example you posted ({awaitdata:true}).
where they use a setTimeout with 1 second pause.
The way I read it, they retry to get the cursor back when lost in regular intervals and return an error iff that failed for a full second.
Aren't these typically bad practices - to leave a stream open [...]?
You're not forgetting the stream (that would be bad), you keep using it - that's pretty much the definition of a tailable cursor.
I have the following architecture:
Ofc. there are ports and adapters, and everything else you can imagine...
What do you suggest, how to send a rest response by immediate consistency? Should I add another event bus and raise an event? (I guess the projection must send something about the success.)
How to handle errors in an event based system like this? (The event bus is not necessary, I can solve loose coupling with an IoC container, but I don't think sending a callback through so many objects would be a good solution.)
It's not hard, instead of sending a command, you can call directly the command handler from controller. Or have a service method which will handle the input and returns something. The important bit is that all these are done synchronously (i.e you need to wait until the handler finishes). The domain events handlers are unaffected, they can be async.
If you don't want to go 'hybrid' and want to always use the same workflow (as described in your pic) things are more complicated, you need the client to check often if the operation has completed. I think the better way is to be flexible so, for some tasks you can use the 'old' ways. The domain events will still be generated and handled, that part would not change. You're just changing the way a 'command' is executed.
Also, it's worth mentioning that you shouldn't expect responses from event handlers and if it makes you feel better, use the 'request-response' terminology instead of command-response.
Btw, you don't break CQRS this way, as long as your domain model isn't used to do queries i.e you have different model for writes and reads, it is CQRS.
Immediate consistency, at what cost? are you using DTC?
What if you later on want to have more than one subscriber for a given event in the read model, how many transactions will be involved in a DTC transaction scope? In order for you to have immediate consistency your events need to be handled sync, so what is the benefit in this architecture?
You can have immediate consistency and even immediate user notifications with client callback (signalR), but IMHO you should changes a few things in your architecture, starting with the drop of the immediate consistency bit.
Why do you think you need that btw?
Observe
I was trying to figure it out how cursor.observe runs inside meteor, but found nothing about it.
Docs says
Establishes a live query that notifies callbacks on any change to the query result.
I would like to understand better what live query means.
Where will be my observer function executed? By Meteor or by mongo?
Multiple runs
When we have more than just a user subscribing an observer, one instance runs for each client, leading us to a performance and race condition issue.
How can I implement my observe to it be like a singleton? Just one instance running for all.
Edit: There was a third question here, but now it is a separated question: How to avoid race conditions on cursor.observe?
Server side, as of right now, observe works as follows:
Construct the set of documents that match the query.
Regularly poll the database with query and take a diff of the changes, emitting the relevant events to the callbacks.
When matching data is changed/inserted into mongo by meteor itself, emit the relevant events, short circuiting step #2 above.
There are plans (possibly in the next release) to automatically ensure that calls to subscribe that have the same arguments are shared. So basically taking care of the singleton part for you automatically.
Certainly you could achieve something like this yourself, but I believe it's a high priority for the meteor team, so it's probably not worth the effort at this point.