jjw24 / Wox

Launcher for Windows, an alternative to Alfred and Launchy.

Home Page:http://wox.one

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Plugin process lifecycle

duurland opened this issue · comments

The process for an executable plugin are currently started after each keystroke, this has quite a few drawbacks imo. The main problem is that the process is stateless, we can not store variables between queries, and any contstructor/init method has to be re-run for each query.

This may be fine for most plugins, but if our plugin for example needs to read a file it would be very excessive to read it on each keystroke, instead of storing its content between queries. If the process was keept alive we could instead use a more event driven approach and continuously listen for input and handle them accordingly, without having to re-read the file.

What if we was able to specify the process lifecycle of our plugin in plugin.json?

Ideas:

  • Always: Keep the process alive, as long as wox.exe is running.
  • Keyword: Keep the process alive as long as our ActionKeyword is matched.
  • Open: Keep the process alive as long as Wox is open.
  • Query: Spawn for each query, the current solution.

One downside to keeping it alive would be that the plugin itself would have to handle the cancellation of async functions whenever the search query changes. But even if the plugin didn't, it should still be a non-issue for Wox to filter out "old" results if the JSONRPC spec was followed and an id (#113) was included.

relevant: #47

nodejs (psuedo) examples of stateless vs event driven plugins

// stateless (current)
const settings = readFile("%APPDATA%/Wox/Settings/Plugins/xx/Settings.json");
const { method, parameters } = parseStdin();

if (method == "query") {
  stdout(/* my result.. */);
}
// event driven
const settings = readFile("%APPDATA%/Wox/Settings/Plugins/xx/Settings.json");
const events = new EventEmitter(); // https://nodejs.org/api/events.html

events.on("query", function(parameters) {
  stdout(/* my result.. */);
});

// listen for stdin
process.stdin.on("data", function(data) {
  const { method, parameters } = parseStdin(data);
  events.emit(method, parameters); // trigger the `method` event
});

Like Alfred, the plugin itself doesn't store database in memory, since that this may waste a lot of resources.
A possible solution is that: if Wox accept a keyword, and the keyword doesn't change, then we will continue to use query method, and any variables the plugin use will be set in init step, so as to avoid reload while we use the same keyword.

Just going to close this as this repo is no longer maintained, feel free to open the issue in Flow if this is still a problem