In general, sardana was designed for using it with client-server architecture. Where all the business logic resides on the server side and client side is just a thin layer to enable control and monitoring.

One of the fundamental principle in sardana design is its clear separation between the core and the middleware. The sardana kernel is composed from objects of the core classes which are then exposed to the clients via server extensions.

Sardana kernel objects communicates using publisher-subscriber pattern in which messages are exchanged by means of synchronous invocation of callbacks. A class inheriting from EventGenerator acts as publisher and a class inheriting from EventReceiver as subscriber e.g. PoolMotor and PoolPseudoMotor respectively or Position and PoolMotor respectively. Moreover this mechanism is used for notifying server extension about sardana kernel events e.g. element’s state change.

Major core classes have state attribute which value is one of the State enum values.

Sardana uses threads for concurrency. More precise using Thread pool pattern implemented in ThreadPool and different instances of such thread pools exist within a kernel.


Due to the use of Tango sardana ThreadPool instances must use special worker threads which execute jobs within EnsureOmniThread context manager.

Logging infrastructure is initialized on server startup using prepare_logging(). Most of the Sardana classes inherit from Logger and you can directly invoke their logging methods e.g. debug(), error(), etc.. For consistency we recommend to use Taurus logging utilities - taurus.core.util.log.