Using actions inside workers - is it possible?
Hey guys! I'm trying to use an action, imported like this:
inside a worker, defined inside
server/workers/doSomething.ts
The markTodoAsDone
action seems to work fine on the client, but I'm not sure if I can use it inside a worker too? It seems it's missing a context.
Is this a natural limitation of how workers work? Or should I be able to use an action there as well?
Thanks π9 Replies
The point of using an action was to receive a UI update on the client (to invalidate the react-query cache basically). If I edit the db directly from the job, this doesn't update the UI on the client.
I can manually provide an argument for context, but in that case, well, I'm missing the context, like User.
Ok, so if your job does an edit to the database, that change won't be picked up by the client automatically, you are right. It will, of course, if client is refreshed, but it won't be "pushed" to the client.
While we are considering adding some direct support for that in Wasp in the future, for now, if you want that, your bet is to use sockets (Wasp has some support for websockets!) to send a message from the server to the client, and then you can react to that message on the client and update the UI if you wish.
In general, calling actions from Jobs should be possible though! Yeah true, they are missing context, but you can construct one, if you have means to. The problem is, you can't really give the action a User, when Job is not being run by User, it is being run by Wasp, to put it that way.
If there was logic in the action you wanted to reuse from Job, what I would do in this case is create a function for that logic, normal JS function somewhere in your server code, I would call it function X, and then your action can call call that function X inside it, and also your job can call that same function X. That way you can share a lot of logic, as much as you want.
Okay, thanks a lot for the insight! π I'll take a closer look at the websockets support in wasp π
Great, and let me know if something is not clear / is cofusing -> I can try to help, or we can maybe even improve the docs if needed!
Thanks, I might have one. I understand that you can get the
io
object inside webSocketFn like this (copied from docs):
But how do I use it elsewhere on the server? Where do I get it from? For example when I want to emit an event from the worker, how do I access the io
? I can't find it in the docs
thanks! π
On the frontend, you can use useSocket
hook to get the socket instance, but how do I get it on the backend?
in my worker, or elsewhere on the backend, I would like to emit an event like io.emit('someMessage', {});
But I don't really have access to io
outside of webSocketFn
. Do you have some example please? πHey @kancur I have some bad and some good news π
We know about this issue: https://github.com/wasp-lang/wasp/issues/1289 -> you can't get the
io
instance outside of the init function easily.
You could hack it like this:
- in the file where you have your init function create a "global" variable that you export from that file. Let's call it let ioInstance = undefined
- then set that ioInstance
to the io
instance you have inside of the init function
- elsewhere in your codebase, import the ioInstance
and use it πGitHub
Enable using the Websocket server inside of server-side code outsid...
Right now, the initialized server is not exposed or documented for the user to use. For example, when somebody likes a post, it might trigger something and a notification is sent over the socket.
Please report back if this worked for you, if not, we'll help you further π
Thanks! I thought about that workaround, but assumed there must be a better way π glad you know about it, will report back after weekend. Thank for you help π
Oh, I forgot to report here, the workaround worked fine, thanks! π
Great to hear that! We'll work on provide 1st party support soon π