DateServiceclass, which is the implementation of our example service. It defines how the service should be started and what action it should perform.
main()function, which creates an instance of
Golemto take care of provisioning our service using the Golem network.
Serviceclass. By overriding certain methods from that class we can define our service's life cycle, as well as its payload. Here's an overview of this interface:
get_payload() -> Optional[Payload]returns the
Payloadobject which describes the execution environment we want our service instances to run on. In the case of the VM runtime this will include a hash of the VM image to be deployed. If we choose not to implement this method our payload will need to be specified when running the service through
start() -> Nonecalled for each service instance when it enters the
startingstate. This should contain the sequence of steps which need to be taken in order for our service to be started.
run() -> Nonecalled for each service instance when it enters the
runningstate. This is where the main loop of our service should be implemented.
shutdown() -> Nonecalled for each service instance when it enters the
stoppingstate. In case our service requires some cleanup logic to be run before an instance is terminated, this is where it should be placed.
shutdown) are optional, although in most cases a service will require at least
startto be implemented.
startfunction is responsible for starting a background process on the provider's exe unit. In the case of
DateServicethis process is going to be the following shell command:
/golem/work/date.txtwith the output of
dateevery 5 seconds.
/golem/work/date.txtwill be our source of data which we'll later on read in our service's
cat /golem/work/date.txtin the provider's exe unit and then retrieve its output by awaiting on
future_results. This gives us an array of objects containing command results which we can use to get the output we need.
mainwe start by creating an instance of
Golem, specifying our budget and target subnet. We then use it as a context manager to run our service.
run_servicewhich, in our example, is given two parameters:
service_classis the class extending
Servicewhich will be used as the definition for each of our service instances.
num_instancesis the number of service instances we'd like to create.
Clusterobject. This is a wrapper around a collection of
Serviceobjects, in our case these will be
DateServiceobjects. Each of these objects represents a single instance of our service provisioned on the Golem network. The
Clustercan be used to control the state of those service instances (e.g. to stop services if necessary).
whileloop will run for a minute, relative to
start_time. After this time the loop will break and we'll exit
Golem's context manager, triggering its cleanup logic.
instancesfield we can iterate over our service instances and inspect their state.
instance.stategives us a
StateMachineassociated with the given instance. It can be in one of five states:
yagnanode active locally (refer to Requestor development: a quick primer in case of any doubts) you can start the example by running the below command from the example's directory:
runningwe start seeing output from the
datecommand running inside the VM. After our set period of time (i.e. 1 minute) the agreement gets terminated and, after paying for the invoice, our program exits.