documentation, notes, images and assorted //things//
| .. | - |
| autocalsniffer.md | 22 days ago |
| graph-memory.md | 5 days ago |
| INDEX.md | 22 days ago |
| m8-memory.md | 5 days ago |
| m8-memory.md~ | 5 days ago |
| marauders-map.md | 22 days ago |
A while back we were trying to decouple a bunch of internal systems from each other. The plan was to roll out an events bus so services could publish what was happening and other services could listen without anyone having to know the shape of the other side.
As a first real use case, we started emitting physical security events — door badge taps, that kind of thing — over a RabbitMQ cluster. And because every events bus needs a demo app to prove it actually works, I built a Marauder's Map. Like the one from Harry Potter. Parchment background, moving footprints, dramatic room names, the lot.
The building already had a centralised access system that emitted door badge and panel events. Every time someone tapped in, we got an event.
I wanted something that felt alive. You open the page and see little footprints lighting up in different rooms. You hover over a room and it tells you who is supposedly in there. A scroll at the bottom announces recent arrivals in suitably dramatic language: "Alice apparated into the Engineers' Hovel," that sort of thing. It was absolutely unnecessary and therefore completely worth doing.
The badge readers published door events to our RabbitMQ cluster. The events looked roughly like "someone badged in at door X at time Y." From that you could infer a room, and from a sequence of doors you could guess movement. The map was just another consumer on the bus — it didn't care where the events came from, and the door system didn't care who was listening.
On the server side I had a small PHP process running a WebSocket server with Ratchet on top of ReactPHP's event loop. It subscribed to the door events, filtered for the ones that actually meant "person entered room," kept a precache of who was where, and pushed updates out to any browser that was connected.
The frontend was plain HTML, CSS, and JavaScript. The fun part was the map itself: an SVG/PNG floor plan with absolutely positioned "hotspot" divs over each room. When the server said someone was in a room, the hotspot went from faint to visible using a footprint icon. Hovering showed a tooltip with names and how long ago they had been seen. After eight hours of no sightings, a room went dim again. People do go home, apparently.
Room names were of couse themed:
I also made an intro page with the classic line: "I solemnly swear that I am up to no good." When you clicked it, the map faded in. Very dramatic. Possibly too dramatic for an office tool.
Surprisingly yes. The accuracy was only as good as the door coverage, which meant it was great for rooms with one door and absolutely hopeless for open areas where people could wander in from anywhere. Sometimes someone would be "in" a room for hours because they had badged in once on the way to somewhere else. Sometimes two people would be marked as in a datacenter because the system had no idea they had left together in the same car.
But the imperfections were part of the charm. It was a toy, not a surveillance system. If you wanted to know whether someone was around, you could check. New hires loved it too.
Unfortunately, eventually it went down because I could not justify maintaining it. A one off toy to demonstrate a system is one thing but its another to maintian it.
The biggest lesson was that sometimes useful tools can be fun. The underlying data was boring. But give it a parchment texture, some cursive fonts, and a few animated footprints and now its funny and almost useful.
Technically, ReactPHP's event loop is a nice fit for this kind of "wait for a message, then fan it out to WebSocket clients" workload, but only in a throw together experement like this. Due to PHPs lack of threads without pthreads it was essentially polling. I also had to set up a precache file which meant the server could restart without losing state, which mattered because I restarted it a lot while tweaking things.
Only if your workplace has a sense of humour.