Code Monkey home page Code Monkey logo

Comments (4)

brianmay avatar brianmay commented on July 29, 2024

Maybe just my state of mind right now, after a stressful morning, but unfortunately I am finding this request hard to follow. :-(

You are talking about outgoing messages, right? Or are you talking about something else?

I might have some ideas to help, but first I have to be able to understand the problem :-).

from tortoise.

m1dnight avatar m1dnight commented on July 29, 2024

That's quite alright, I can't explain all that well, but I tried.

My initial problem was that receiving events from MQTT is a concern that you handle with functions in the Tortoise handler (i.e., implement the right handle_message/3 callbacks). But the concern of sending an event from Elixir to the MQTT (e.g., "turn on lamp xyz") should also be a concern that you implement in that same handler module. But you cannot send a regular message to the handler process (e.g., send(HandlerId, {:foo, :bar})) because you cannot implement callbacks for those messages in the Tortoise.Handler module. In GenServer these are the handle_info/3 callbacks.

The thing I did not notice right away is that sending a message is just a function call (Tortoise.publish/3), so I ended up adding functions in the module myself that use Tortoise.publish/3, and that works too, but I was wondering if there was a more idiomatic approach.

from tortoise.

gausby avatar gausby commented on July 29, 2024

The module you use for your tortoise handler is supposed to do very little, because it is running in the tortoise controller process, which means that an error in this part of the code would result in a tortoise crash, and while the code is running the controller is blocked: While most MQTT connections are not high volume I recommend doing as little as possible in the tortoise controller, and just route the messages to a process where you have all your logic for your application.

Would that work for you ?

from tortoise.

brianmay avatar brianmay commented on July 29, 2024

For myself[1], I ended up creating a process that receives subscribe requests from processes (e.g. scenic scenes, Phoenix live handlers, etc), and it routes the messages to the processes that have requested them. See https://github.com/brianmay/robotica-elixir/blob/master/robotica_plugins/lib/subscriptions.ex [2]. The tortoise handler is here: https://github.com/brianmay/robotica-elixir/blob/master/robotica/lib/robotica/client.ex#L84

It also keeps track on the last received message, and re-sends it on a new subscription. Ideally this probably should only happen for retained messages, but I couldn't work out how to tell them apart. For my use case all messages are retained.

It also doesn't support wildcard subscriptions. I haven't needed them.

Unfortunately, I couldn't get dynamic MQTT subscriptions to work reliably. See #130. So the mqtt subscriptions need to be hardwired into the initialization code. But regardless, this code still serves my purpose. The filtering of unwanted messages will occur in my code, not the mqtt server. If I ever got dynamic subscriptions working, I probably would want to listen to connection(:up, state) and reconnect to all subscriptions. As currently I think tortoise might forget dynamic subscriptions on reconnect (although I guess this might change also).

Thinking about what @gausby said, possible the message() function should be a cast not a call. But the routing shouldn't really take too long, and the actual sending is done via cast.

Notes:

[1] Code is "first working draft" status. It works, but readability probably can/should be improved now.
[2] Name subject to change because module name is misleading. I initially created RoboticaPlugins to do plugins stuff, but now it is everything except plugins stuff!

from tortoise.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.