Day 2: It does something
Jake Gaylor edited this page 2015-04-20 21:52:56 -05:00

Today, the bot learned a few new commands and has a new pipeline for requesting remote data, cacheing, processing, and returning results.

I needed to be able to develop locally without a 5 minute deadzone in my io loop while dockerhub built my image and tatum redeployed them. I've added some local.sh files to my development machine that set all the necessary environment variables and start the necessary process. I've gitignored them because they contain sensitive information, but they are there, silently improving my workflow.

Inside of StatBotAPI I found some code that I wrote previously that abstracted a lot of the nitty gritty of making new commands. It was in desperate need of rewriting and in some places incomplete, but it provided a solid base to move forward with.

The general idea behind most commands is that they need to grab data from one or more remote sources, compile the data, and process the data into a meaningful response. LoLHubot is responsible for processing the chat command, sending a request to StatBotAPI, processing the response and sending a message back to the requester. StatBotAPI takes requests from LoLHubot, gathers and compiles the necessary data, and responds with the composite data object.

It is important that StatBot cache the results of remote calls whenever possible. The time that a source should remain fresh can vary from source to source, and sources often get requested with differing parameters. Our cacheing solution needed to be sensitive to both of these needs.

Each distinct remote request can be modeled as a DataSource (code). Each DataSource is named and combines a cache timeout, a cache instance, a getter, and a function to convert the data source's name and options to a unique key. The getter is called whenever someone requests the data source's value and it is not cached. When a getter is called, the return value is cached at the key returned by keyFn. It is possible that multiple calls will be made requesting the value of a data source before the getter has returned. DataSources are aware of this and will return a single promise for the value to all requesters, preventing spamming remote calls while waiting for the first to be fulfilled.

Commands consume the values provided by DataSources. A Command is responsible for processing one or more DataSources into a single object to be returned to the requester, LoLHubot. Commands are simply an association between a name and a buildFn which is called when the Command is run. The buildFn is where the Command does its work and has access to options the Command was run with as well as the getters for each DataSource it depends on.

Commands are wrapped in express handlers to expose via an HTTP api. The express handlers are responsible for processing the request object for arguments, running commands with the provided arguments, and returning the results of the commands to the requester.