Introduction to Cyclotron

So far, the code written in this book was done completely from scratch. This is great to learn how to write code, but there is some boilerplate that always has to be written:

  • Creating and running the AsyncIO event loop
  • Managing observable cycles with subjects

Cyclotron is a set of Python packages that aims at implementing this boilerplate instead of having to rewrite it again and again. It also defines a common prototype for ReactiveX components and drivers so that they can be shared between projects. Cyclotron is composed of several packages:

  • cyclotron: This is a very small package that manages the connection of observables, with the support of observable cycles.
  • cyclotron-std: This package contains drivers and helpers to use some features of the Python standard library with RxPY.
  • cyclotron-aio: This package contains helpers to deal with AsyncIO. It allows us to start the event loop and contains some drivers based on other AsyncIO packages.

The following packages are available on PyPI and can be installed with pip:

pip3 install cyclotron
pip3 install cyclotron-std
pip3 install cyclotron-aio

The main feature of Cyclotron is implementing the base code of the functional and reactive design that was described in Chapter 3, Functional Programming with ReactiveX. For this, Cyclotron defines the following entities:

  • Runners
  • Components and drivers
  • Sources and sinks

Runners are functions that are used to execute the entry point of the program, with drivers being configured and connected together (eventually with cycles in the connection). The cyclotron package contains a basic runner that just connects the observables together and starts the drivers. This runner can be used directly in applications that do not use AsyncIO. Applications that are based on AsyncIO can use the runner provided in the cyclotron-aio package. This one is based on the runner of the cyclotron package, but it also starts the AsyncIO event loop.

Components are functions that take observables as input and return observables as output. Components are reusable via composition. The entry point of a runner is a component, and components can use other components. This makes the entry point of the application a function like any other component of the application. A nice benefit of this property is the fact that a complete application can be used as a component in another application. The following figure shows an example of an application using several components:

Figure 6.2: Component composition; the topmost component is the entry point of the application

Drivers are specialized components; they are components that implement side-effects. However, a driver has a similar prototype to a component. It takes observables as input and returns observables. The important difference between a component and a driver lies in their behavior. A component is a pure function while a driver is a side-effect.

Sources and sinks are the inputs and outputs used by components and drivers. As already shown in Figure 3.4, components take a source object as input and return a sink object. On the other hand, drivers take a sink object as input and return a source object. These inputs and outputs are not directly observables, but named tuples with each field being either an observable (for drivers), or another named tuple (for components). As explained in the previous section, using named tuples has several benefits. The syntax to use them is easier than dictionaries, they are very efficient, and they are immutable. The following figure shows a reminder of the inputs and outputs used by components and drivers:

Figure 6.3: Inputs and outputs of components and drivers

Each driver defines a source named tuple that it returns and a sink named tuple that it accepts. The fields of these named tuples are observables. Each component also defines a source-named tuple that it accepts and a sink-named tuple that it returns. However, since a component can interact with several drivers, the fields of these named tuples are not directly observables, but the source and sink named tuples defined by the drivers.

Let's clarify how to use all these entities with another implementation of the CLI echo example studied in Chapter 1, An Introduction to Reactive Programming.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.181.47