jjw24 / Wox

Launcher for Windows, an alternative to Alfred and Launchy.
http://wox.one
MIT License
154 stars 12 forks source link

Plugin process lifecycle #114

Closed duurland closed 3 years ago

duurland commented 4 years ago

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:

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

duurland commented 4 years ago

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
});
HsunGong commented 4 years ago

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.

jjw24 commented 3 years ago

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