I’m creating a chatbot in Java for Slack which looks as follows:
To understand this diagram, think of the “Bot” process as a Slack user that, instead of being a human, is a computer program.
There are two components, the chatbot itself and a syntax parser. The parser takes a long time to start up, so I can’t just launch the parser for each message processed by the the chatbot. Rather the parser must be always running and respond to queries from the chatbot.
I want to deploy all the components to Heroku. As far as I have seen, there are three options to deploy these components:
- Bot and parser on the same dyno in the same application
- Bot and parser on separate dynos in the same application
- Bot and parser in separate applications
The question is how to best achieve a synchronous two-way communication between the two components.
So far I looked at the following possible solutions:
Option 1: bot and parser on same dyno
- Use named pipes as shown here: this is an error-prone and non-portable solution
- TCP sockets (set up parser as a server and bot as a client and communicate through
localhostand some port): this worked on AWS EC2 (through AWS Elastic Beanstalk), however, it seems to not easily work on Heroku (as discussed here), and I want to migrate from AWS to Heroku
Option 2: bot and parser on different dynos in same application
- TCP sockets: it’s not a solution here, since processes running on different dynos cannot communicate with each other, as to the documentation here
- Third-party Heroku messaging and queueing add-on: use one of these add-ons, for example, IronMQ
Option 3: bot and parser in different applications
- Run parser as a
webprocess and expose a REST interface that the chatbot can access
- Third-party Heroku messaging and queueing add-on: this should work in the same way as in Option 2
What to do?
I would prefer to decouple the components, so I tend to Option 2 and Option 3.
A message queueing add-on would certainly work, but aren’t they all targeted at asynchronous communication? Because I need only synchronous communication. There’s no gain if the request to the parser returns immediately, because the bot can anyway only reply to a message when the result of the parser is available. So, asynchronous communication might be an overkill here.
Did I miss any possible solution? And what would be robust and efficient architecture for this use case?