Config generators and skinny Resque jobs
This release brings a significant change, but should be backwards compatible and shouldn't rely on any changes to upgrade.
That said, you will see some deprecation notices.
The main change is the introduction of 'Config Generators'. Before explaining what these are, it helps to understand what motivated their need.
Previously, Tripod's configuration was managed via Tripod\Mongo\Config
, which took a fully fleshed out array of configuration options and loaded it as a singleton which was reused throughout the lifecycle of the session.
However, it's necessary that the asynchronous workers also have access to the same config. To accomplish that simply and independently (i.e. workers didn't need to know anything about the environment that created them), Tripod passed the entire configuration as a job argument. Given that Tripod requires a lot of configuration to work, this led to extremely enormous jobs (our average Resque job size was ~46KB) with massively redundant data (while we have about 100 different configurations we pass to Tripod, they rarely change) which then requires considerably larger memory overhead in Redis.
Instead, we've now provided the option to replace \Tripod\Mongo\Config
with your own objects that implement \Tripod\Mongo\IConfigInstance
. These classes need a serialize
instance method and deserialize
class method that can provide all the context needed to fill out the config.
This is probably easiest to visualize using an example from the test suite. We have created an extremely simple config generator that gets its config from a static JSON file and extends \Tripod\Mongo\Config
.
<?php
class FileBasedConfigGenerator extends \Tripod\Mongo\Config
{
protected $fileName;
private function __construct()
{
}
public function serialize()
{
return ['class' => get_class($this), 'filename' => $this->fileName];
}
public static function deserialize(array $config)
{
$instance = new self();
$instance->fileName = $config['filename'];
$cfg = json_decode(file_get_contents($config['filename']), true);
$instance->loadConfig($cfg);
return $instance;
}
}
This basically uses all of the plumbing that \Tripod\Mongo\Config
has already laid out, but the footprint in the jobs would be:
{
'class' => 'FileBasedConfigGenerator',
'filename' => '/path/to/your/config.json'
}
Then, assuming that class FileBasedConfigGenerator
is available to Tripod and its workers, you are ready to go.
There are some changes to Tripod that were required for this, however. Previously, you would set your Tripod config like this:
$conf = some_way_to_get_configuration_array();
\Tripod\Mongo\Config::setConfig($conf);
And access the configuration instance like this:
\Tripod\Mongo\Config::getInstance()
This will still work for the time being, but you will get warning log lines with a deprecation notice.
Instead, you will now do something more like:
$conf = ['class' => 'MyConfigGenerator']; // although you can still use the exact same method as above
\Tripod\Config::setConfig($conf); // Note the change of namespace
\Tripod\Config::getInstance();
The last line here will call \Tripod\ConfigFactory
and instantiate your config instance if it hasn't already been created.
Since we were using our own experience earlier for reference, to show the effect of this, the same Resque job size mentioned that was ~46KB went down to ~1.5KB, a nearly 97% decrease.