package lsr.service;
import lsr.paxos.replica.Replica;
import lsr.paxos.replica.SnapshotListener;
/**
* This interface represents state machine with possibility to save current
* state (snapshot). It is used by {@link Replica} to execute commands from
* clients, for making snapshots, and also to update the state from other
* snapshot (received from other replica).
* <p>
* All methods are called from the same thread, so it is not necessary to
* synchronize them.
* <p>
* After creating new snapshot by this <code>Service</code>, all
* <code>SnapshotListener</code> should be called. They shouldn't be called
* after updating state machine from snapshot (see <code>updateToSnapshot</code>
* for more details).
* <p>
* This interface provides two methods used for notifying that the snapshot
* should be made. First is only asking for snapshot, which can be ignored if
* for service it is bad moment for creating snapshot. Second methods is called
* when logs are much bigger than estimated size of next snapshot.
* <p>
* For some methods, also request sequential number is provided. It is used to
* determine when the snapshot by <code>Service</code> was made. The number of
* created snapshot is last executed request.
*
* @see Replica
* @see SnapshotListener
*/
public interface Service {
/**
* Informs the service that the recovery process has been finished, i.e.
* that the service is at least at the state later than by crashing.
*
* Please notice, for some crash-recovery approaches this can mean that the
* service is a lot further than by crash.
*/
void recoveryFinished();
/**
* Executes one command from client on this state machine. This method will
* be called by {@link Replica} in proper order. The number of request is
* needed only for snapshot mechanism.
*
* @param value - value of instance to execute on this service
* @param executeSeqNo - ordinal number of this requests
* @return generated reply which will be sent to client
*/
byte[] execute(byte[] value, int executeSeqNo);
/**
* Notifies service that it would be good to create snapshot now.
* <code>Service</code> should check whether this is good moment, and create
* snapshot if needed.
*
* @param lastSnapshotNextRequestSeqNo - specified last known snapshot; is
* used to determine duplicate calling of method
*/
void askForSnapshot(int lastSnapshotNextRequestSeqNo);
/**
* Notifies service that size of logs are much bigger than estimated size of
* snapshot. Not implementing this method may cause slowing down the
* algorithm, especially in case of network problems and also recovery in
* case of crash can take more time.
*
* @param lastSnapshotNextRequestSeqNo - specified last known snapshot; is
* used to determine duplicate calling of method
*/
void forceSnapshot(int lastSnapshotNextRequestSeqNo);
/**
* Registers new listener which will be called every time new snapshot is
* created by this <code>Service</code>.
*
* @param listener - the listener to register
*/
void addSnapshotListener(SnapshotListener listener);
/**
* Unregisters the listener from this service. It will not be called when
* new snapshot is created by this <code>Service</code>.
*
* @param listener - the listener to unregister
*/
void removeSnapshotListener(SnapshotListener listener);
/**
* Restores the service state from snapshot
*
* @param nextRequestSeqNo (last executed request sequential number + 1)
* before snapshot was made (i.e. next request to be executed no)
* @param snapshot the snapshot itself
*/
void updateToSnapshot(int nextRequestSeqNo, byte[] snapshot);
}