@composi/runtime:

Stop Program

Shutting Down a Program's Processes

When you run a program, that returns a function to shut down the program. In this snippet we have the simplest possible program. We run and capture its shutdown function and then stop it:

import { run } from '@composi/core'
// Run a simple program and capture its
// shutdown function in variable:
const endProgram = run({
  init() {},
  view(state, send) {},
  update(state, msg, send) {}
})
// Three seconds later stop the program:
setTimeout(() => endProgram(), 3000)

When your program has effects that run timers, you'll want a way to make sure you can shut them down. Otherise, even after your app ends, the timers can keep running, consuming browser memory until it crashes. The following Codepen illustrates this problem. It has a setInterval to output the time by sending a message to an update action. The effect also logs a count to the console.

See the Pen @composi/core + runtime Clock-3 by Robert Biggs (@rbiggs) on CodePen.

Open the pen in its own window by clicking on the Codepen logo in the upper right. Then scrolldown to the bottom of the JavaScript panel. You'll see that when we run the program, we capture its return value in a variable stopProgram. You can open by Codpen console in the bottom right by clicking and dragging it up. You'll see that the effect is also logging a count to the console. Now if you click in the console entry, type stopProgram() and hit enter, the program will stop. You can tell because the the clock component is no longer update in the HTML. But you'll notice that the effect is still running independently of the program, logging the count in the console. The following image shows how to do this:

Image of a Codepen example of how to stop a program from running.

Having effects running after the program stops produces memory leaks. This is a big problem. But there is a simple solution to this, as explained next.

Done()

So far we have always talked about @composi/core runtime programs having three properties: init, view and update. This is the basics to have a program that can run. But you can also provide a fourth optional property: done(). This method will get called when you stop your program. You can use it to do cleanup before the program stops. The done method gets the application state passed to it.

import { run } from '@composi/core
const program = {
  init() {},
  view(state, send) {},
  update(state, msg, send) {},
  // Escape hatch:
  done(state) {
    // Clean up any running effects here...
  }
}

// Start program:
const endProgram = run(program)

// Later:
endProgram()
// Stopping the program will first invoke the done() function,
// allowing us to clean up any running effects.

And here's our clock Codepen updated so that when we stop the program, the effect also stops. We've added a done() method to our program to stop the setInterval. You can open the Codepen in its own window. Then open the console and enter stopProgram. Now you'll see that the clock stops, and the setInterval also stops, no longer logging to the console.

See the Pen @composi/core + runtime Clock-4 by Robert Biggs (@rbiggs) on CodePen.