-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow programmatic launching of hubot #858
Comments
Open question: what, if any, of this needs to be asynchronous? We may be able to keep the launch config file synchronous, but permit a different way of loading that has async calls. Given the nature of JavaScript, I think we always want to provide some mechanism for async extensions. Example: Generate a module asynchronously (e.g. pull data from JIRA), load it (could this ever be async?), and finally start the robot (connect the adapter) # part of my custom node application
robot = new Robot(<stuff>)
asyncFunctionToGenerateModules 'my-module', (genModule) ->
robot.useAsync genModule, () ->
robot.run |
This a great writeup, thanks for putting it together!
I'm not so sure about this one. I think some might interpret this as being say, launchable from express application cc #815. That is a bit more complicated because of hubot's builtin express router cc #767
How are we defining legacy scripts exactly? Preferably, we'd have backwards compatability with the hubot-scripts package, as well as npm script packages.
Definitely out of scope. The problem with multiple adapters is more about user identify and persistence.
That is going to be more complicated, because of the builtin adapters. That is probably an argument they should be made external to hubot though. I also tend to think of the adapter used as more of a run-time decision. That is, I might run in development with shell, test with the mock test adapter, and run in production with campfire, so having that be programatic is less interesting I think.
I'm not sure about this bit either. If you are making a new robot instance, you'd also have to manage all the lifecycle events. I'm also not sure what the difference between a legacy and non-legacy script is at this time. Preferably,
That's a good question. I'd prefer sync for the initialization, because then you can know when you have a bootable hubot. I guess you'd be able to async some things, like polling an external service to dynamically create listeners, but practically speaking you'd want all the core things (like rbac) to be loaded up front before firing of those. Aside from what you've brought up, two other points I'd consider:
Kinda tied together, but I'd suggest generating a index.coffee in new hubots, and then in the generated bin/hubot shell script (not to be confused with github/hubot's bin/hubot), tell it to use that 'launch config file'. |
Thanks for the feedback! A few quick overarching thoughts:
As I understand it, the long-term goal is to pull Express out of the core. I would be okay assuming #767 is a dependency for embedding hubot in an existing Express server (but we could start working on the new structure without it).
Legacy scripts are scripts that follow the current model of
In particular, I'd like to move module resolution out of hubot core. loadFile doing path resolution, extension checking, and module loading just feels really dirty (and has caused me pain in a couple of places). I'd like for all
My (untested) thought was to rely on protypical inheritance extend the Robot instance. This way, a script that tries to set up I like the idea of making
I haven't thought about it too much, but I think so. Eventually, I'd like to strip down pretty much everything that is in
Erm.. not sure, but I would assume it would get updated if the script interface changes.
I'm going to need to dig into that some more. I don't (yet) fully understand the boot process, but I expect to before I start making changes. |
cc #847 as well, as that'd let users require newrelic up at the top of their launch config. |
Another thing to think about: if we start sharing the Express server (or even colocating multiple bots), how do URL paths look? cc: #622 Not sure this is even something that we want to support, but should be considered. |
That's a good question. I'm not sure it's something this feature needs to be concerned about yet. I think having express be extracted out will be a bit easier with this feature implemented. |
As discussed in several other issues (#514, #768, #801, #815), there is a desire for a programmatic way of launching hubot to control script loading and to combine with existing node applications.
The proposed solution is something along the lines of Rack's config.ru (which I'll reference as the "launch config file").
Primary design constraints:
Not really in scope, but could we make it so that a robot can be attached to multiple adapters?
Terminology:
script
is the current style of scripts (module.exports
is aFunction
that is called with therobot
object)module
is the new-style of scripts; details are undefined other than it can be more than just aFunction
and could have a namespace for all listeners it registersAn initial pass at the design:
Breakdown:
Maybe stick with the current script interface? This could make forward-compatibility possible (which would make moving to the rackup file optional and not require a major version bump).
Could we make adapters just another module? Not sure what the implications are for the underlying implementation.
Load middleware in whatever order makes sense (since order matters for middleware)
wrapLegacyScript
allows for loading of old-style scripts. It creates a new robot object that extends the real robot so that the legacy script is completely isolated; sandboxes naughty scripts that modify the global robot object. This also implies that new-style scripts will have a namespace that needs to be supplemented ('mysql' in this example)."Standard" module loading method. Just pull in a module and hand it over to the robot. This suggests that a module is more than a function that needs to be called. This could also permit very interesting patterns around generating scripts at load-time (a la #813). If each module has a unique namespace for all listeners, you could even have dynamic unloading of modules.
Some other little tidbits I came up with:
Open questions/requirements
The text was updated successfully, but these errors were encountered: