Log and apply a state change.

        This function will first write the state change to the write-ahead-log,
        in case of a node crash the state change can be recovered and replayed
        to restore the node state.

        Events produced by applying state change are also saved.

def log_and_dispatch(self, state_change):
        """ Log and apply a state change.

        This function will first write the state change to the write-ahead-log,
        in case of a node crash the state change can be recovered and replayed
        to restore the node state.

        Events produced by applying state change are also saved.
        """

        with self._lock:
            timestamp = datetime.utcnow().isoformat(timespec='milliseconds')
            state_change_id = self.storage.write_state_change(state_change, timestamp)
            self.state_change_id = state_change_id

            events = self.state_manager.dispatch(state_change)

            self.storage.write_events(state_change_id, events, timestamp)

        return events