# Broker lifecycle

This section describes what happens when the ServiceBroker starts or stops.

# Starting logic

When the broker starts Transporter to connect to other nodes, does not yet publish the local service list. It starts all the Services first (calls the "started" handler) and then publishes the service list to the other nodes. Hence remote nodes send requests only after all local service are started properly.

Circular references

Dead-locks can be made when two services wait for each other. For example "users" service has a dependency to "posts" service and "posts" has a dependency to "users". Three or more services can cause deadlock at startup when referenced to each other circularly. Circular references cannot be automatically blocked by ServiceBroker, so the startup sequence must be well planned.

# Stopping logic

When you call "broker.stop()" the Service Broker sends a "DISCONNECT" message to remote nodes, so they can route the requests to other instances instead of services under stopping. Then the ServiceBroker stops all local services and the Transporter.

# Service lifecycle

This section describes what happens when a service is starting & stopping and how you should use the lifecycle event handler.

# "started" event handler

It is triggered when the broker.start is called and the broker starts all local services. Use it to connect to database, listen servers...etc.

















 








import services.moleculer.ServiceBroker;
import services.moleculer.cacher.Cacher;
import services.moleculer.service.*;

@Name("test")
public class TestService extends Service {

    /**
     * Object to initialize
     */
    private Cacher cacher;

    /**
     * Starting the Service instance...
     */
    @Override
    public void started(ServiceBroker broker) throws Exception {
        super.started(broker);

        // Custom initialization code
        cacher = broker.getConfig().getCacher();
        // ...
    }
}

To register for the above Service at the Service Broker:

ServiceBrokerConfig cfg = new ServiceBrokerConfig();
cfg.setNodeID("node1");
ServiceBroker broker = ServiceBroker(cfg);
broker.createService(new TestService());
broker.start();

# "stopped" event handler

It is triggered when the broker.stop is called and the broker starts stopping all local services. Use it to close database connections, stop Executors and Timers, close sockets...etc.







 






import services.moleculer.service.*;

@Name("test")
public class TestService extends Service {

    @Override
    public void stopped() {
        super.stopped();
        
        // Release resources...
    }
}

If you use Spring, the above "started" and "stopped" functions should not be called by Spring as init-method or destroy-method). These functions are invoked in all cases by the ServiceBroker, not by the Spring Framework. However, you can create "init" / "destroy" functions for Spring, regardless of the "started" / "stopped" functions. In this case, the start and stop order is as follows:

import javax.annotation.*;
import org.springframework.stereotype.Controller;
import io.datatree.Tree;
import services.moleculer.ServiceBroker;
import services.moleculer.service.*;

@Name("test")
@Controller
public class TestService extends Service {

    // --- STARTING SERVICE ---
    
    public TestService() {

        // 1.) The constructor is called first
    }

    @Override
    public void started(ServiceBroker broker) throws Exception {
        super.started(broker);

        // 2.) Initialize service - all local Services are
        // registered but only some of them have been started

        // Registered Services are accessible as follows:
        // xyzService = (XyzService) broker.getLocalService("xyz");
    }

    // --- RUNNING SERVICE ---
    
    public Action action = ctx -> {

        // 3.) This Action is called by other Actions
        // Request: { "foo": 5 }
        int foo = ctx.params.get("foo", 0)

        // Response: { "result": 8 }
        return new Tree().put("result", foo + 3);
    };

    // --- STOPPING SERVICE ---

    @Override
    public void stopped() {

        // 4.) Invoked by the Service Broker before the shutdown
    }

    @Override
    protected void finalize() throws Throwable {

        // 5.) This called last by the Garbage Collector
    }
}