project-flogo / flogo-web

Project Flogo Web UI
http://flogo.io
BSD 3-Clause "New" or "Revised" License
65 stars 36 forks source link

Enhance engine process management #1249

Open fcastill opened 5 years ago

fcastill commented 5 years ago

Is your feature request related to a problem? Please describe.

In the past we only had one reason to start an engine process and that was to test-run a flow. The engine process is started on the background and waits in there in case an user wanted to test-run/debug a flow.

Now, we have 2 use cases for the engine instance:

  1. Same as before: to test-run a flow
  2. To simulate a stream

Each use case requires different environment variables to be set as each use cases needs different configuration. Also, in the case of the stream, it needs to prepare additional configuration files to be provided to the engine (basically output a flogo.json to be ran).

We need a way to control the engine instance that is running in the background and ensure there's only one instance at a time as well as we need to allow to customize that instance every time it needs to be re-instantiated to support the different configurations that different types of actions/resources might require.

Another thing to consider is that actions/resource types are now pluggable, the configuration logic should reside in the plugins to allow new types of resources/actions to be easily added.

Describe the solution you'd like

  1. Implement an EngineProcessDirector class which will centralize the management of the process instance. By centralizing the process instance we can keep track of it and its status as well as force stop it if necessary. Any resource/action that wants to interact/create an engine process needs to do it through the EngineProcessDirector. When the EngineProcessDirector is requested to start a new process it will need to stop the previous running service if any before starting the new process.
  2. Move the logic to that is specific to the flow runner and the stream simulator to their respective plugins and provide the plugins with access to the EngineProcessDirector.

Interfaces

/**
Manages the instance of the engine process to ensure there's only one process running at a time.
*/
interface EngineProcessDirector {
   status = 'running' | 'stopped';
   acquire(config: EngineProcessConfig): Promise<ChildProcess>;
   /* Kill running process if any */
   kill(): Promise<void>;
}

/**
Configuration that can be provided when acquiring a new instance from the `EngineProcessDirector`
*/
interface EngineProcessConfig {
   /** will be called to resolve the environment variables to provide to the engine */
   resolveEnv?(): { [key: string]: string }
   /** will be called before starting the process, can be used for initialization */
   beforeStart?(): void
   /** will be called after starting the process */
   afterStart?(instance: ChildProcess): void
   /** will be called when the process has been stopped */
   afterStop?(reason): void
}

Usage in plugins

function startStreamSimulation(processDirector: EngineProcessDirector) {
   const processDirector.acquire({
      resolveEnv = () => ({ SOME_ENV_VAR: 'foo' }),
      afterStart(instance: ChildProcess) {
        // do something with the instance
      },
      afterStop() {
        // dome some cleanup
      }
   });
}

Installing a new contribution

When installing a new contribution the installation manager can call engineProcessDirector.kill() to make sure that process won't conflict with the installation.