public bool HandleCommand(ICommand cmd) { if (cmd is LockStateChangedCommand chCmd) { lock (_ownersLock) { if (!chCmd.Locked) { _owners[chCmd.Index] = LockOwner.None; } else if (!_owners.ContainsKey(chCmd.Index) || _owners[chCmd.Index] == LockOwner.None) { _owners[chCmd.Index] = LockOwner.Other; } } return(true); } if (cmd is LockObtainedCommand obCmd) { lock (_ownersLock) { _owners[obCmd.Index] = LockOwner.This; GotLock(obCmd.Index); } return(true); } lock (_jobLock) { if (_currentJob == null) { // TODO - send error? return(false); } // The atem sends this 'error' while we are not allowed/able to download the asset. we should keep retrying the same start until it succeeds // Note: perhaps this means that someone else has the lock, but we have the lock which will become valid once their transfer completes? if (cmd is DataTransferErrorCommand errCmd && _currentId == errCmd.TransferId) { // This can happen sometimes, and we should retry until it works if (errCmd.ErrorCode == DataTransferError.TryAgain && _currentStartCommand != null) { _connection.QueueCommand(_currentStartCommand); return(true); } // The asset was not found, or some unknown error meaning we should fail and move on if (_currentJob != null) { if (errCmd.ErrorCode != DataTransferError.NotFound) { // We don't know the error, so abort the transfer _connection.QueueCommand(new DataTransferAbortCommand { TransferId = _currentId }); } ReleaseLock(_currentJob.StoreId); _currentJob.Fail(); _currentStartCommand = null; _currentJob = null; } // Try and get next job started DequeueAndRun(); return(true); } if (cmd is DataTransferCompleteCommand completeCmd && _currentId != completeCmd.TransferId) { // TODO - should we try and start our job? return(false); } if (!AcceptedCommands.Contains(cmd.GetType()) || !_currentJob.StartedAt.HasValue) { return(false); } var res = _currentJob.OnMessage(cmd, _connection); switch (res) { case DataTransferStatus.OK: break; // Job is still working away case DataTransferStatus.Success: ReleaseLock(_currentJob.StoreId); _currentStartCommand = null; _currentJob = null; DequeueAndRun(); break; case DataTransferStatus.Unknown: // Command was not handled, this is probably ok // TODO - we should track the time of the last handled command so we can check for stuck transfers return(false); } return(true); } }
public bool HandleCommand(ICommand cmd) { if (cmd is LockStateChangedCommand chCmd) { lock (_ownersLock) { if (!chCmd.Locked) { _owners[chCmd.Index] = LockOwner.None; } else if (!_owners.ContainsKey(chCmd.Index) || _owners[chCmd.Index] == LockOwner.None) { _owners[chCmd.Index] = LockOwner.Other; } if (!chCmd.Locked) { LostLock(chCmd.Index); } } return(true); } if (cmd is LockObtainedCommand obCmd) { lock (_ownersLock) { _owners[obCmd.Index] = LockOwner.This; GotLock(obCmd.Index); } return(true); } lock (_jobLock) { if (_currentJob == null) { // TODO - send error? return(false); } if (!AcceptedCommands.Contains(cmd.GetType()) || !_currentJob.StartedAt.HasValue) { return(false); } var res = _currentJob.OnMessage(cmd, _connection); switch (res) { case DataTransferStatus.OK: break; // Job is still working away case DataTransferStatus.Success: _currentJobCompleted = true; if (HoldsLock(_currentJob.StoreId)) { ReleaseLock(_currentJob.StoreId); } else { _currentJob = null; } break; case DataTransferStatus.Error: // TODO - send error _currentJobCompleted = true; if (HoldsLock(_currentJob.StoreId)) { ReleaseLock(_currentJob.StoreId); } else { _currentJob = null; } break; } return(true); } }