What the system is made of
The three services behind the CloudFly Helpdesk console, the path a message takes through them, and why losing the realtime link is not losing a message.
The console you open each morning is one of three services that run independently of one another. Knowing how the three divide the work is enough to read two familiar situations: a colleague's message appearing the instant they send it, and the status line reporting a lost connection.
This page describes the shape of the system at the level a console user needs,
not at the level of whoever deploys it. Ports, environment variables and build
steps live in the README.md file in the source tree.
Three services, three different jobs
| Service | What it does | What it does not do |
|---|---|---|
| Console (the web interface) | Draws the queue, sends REST requests, holds one Socket.IO connection | Never reads the database directly |
api-engine | Answers every REST request and is the only writer to the database | Does not push data into a browser on its own |
ws-engine | Replays events down to the browsers watching a given conversation | Never writes to the database |
The three share no code. They meet in exactly two places: Postgres, where everything is stored, and Redis, the internal line between the two engines.
The chat panel on a customer's website talks to api-engine as well, through
its own widget door and with its own token. One body of data, two entrances,
and each entrance has its own reach.
The path a message takes
- A customer or you sends a message. The request reaches
api-engineover REST. api-enginewrites the message into Postgres and waits for the write.- Once the row is committed, it publishes a
message.createdevent on the Redischat_eventschannel. ws-engine, listening on that channel, turns it into anew_messageevent and pushes it into the room for that conversation.- Every browser holding that conversation open appends the message, with no page reload.
That is why a message shows up almost instantly in a colleague's window: it waits for nobody to press refresh, it travels the Redis line down to the socket.
Write first, publish second
The order of steps 2 and 3 is a promise the system keeps, not an accident. The realtime event is born after the row is already in the database.
Two consequences worth remembering. First: a message you watch land in the
thread has been stored, and a page reload still shows it. Second: the reverse
cannot happen, because ws-engine holds no write access, so no message ever
lives on the socket alone.
Losing the realtime link costs you live updates, not data. Messages are still written as usual and all of them are there when you reopen the conversation, because that read goes over REST rather than over the socket.
What you observe when a part stops
| Part that stops | What you observe |
|---|---|
ws-engine or Redis | Messages still send and still store; open windows stop updating themselves and need a reload to show new traffic |
api-engine | Nothing sends and no queue opens: every REST request goes through it |
| Postgres | No service can work at all, since this is where the data lives |
The table gives you something an operations engineer can act on: "I can send but I cannot see other people's messages" and "I cannot send" point at two different broken areas.
Read next
Invite a colleague into the workspace
Create an account for a colleague in CloudFly Helpdesk: fill in the profile, pick the workspace role, set a starting password, then place them in groups.
Shared inboxes and channels
How a shared inbox differs from a connected channel in CloudFly Helpdesk, and why every conversation belongs to exactly one inbox at a time.