public async Task <bool> TryToUnlockAsync(string id, string ownerId, string ownerType) { await this.SetupStorageAsync(); try { // Note: this can throw ResourceNotFoundException IDataRecord record = await this.GetAsync(id); // Nothing to do if (!record.IsLocked()) { return(true); } if (!record.CanUnlock(ownerId, ownerType)) { this.log.Debug("The resource is locked by another client and cannot be unlocked by this client", () => new { this.storageName, id, ownerId, ownerType }); return(false); } record.Touch(); record.Unlock(ownerId, ownerType); var entity = (DataRecord)record; var operation = TableOperation.InsertOrMerge(entity); TableResult response = await this.tableStorage.ExecuteAsync(this.tableStorageTable, operation); switch (response.HttpStatusCode) { case (int)HttpStatusCode.PreconditionFailed: this.log.Info( "ETag mismatch: the resource has been updated by another client.", () => new { this.storageName, Id = record.GetId(), ETag = record.GetETag() }); throw new ConflictingResourceException("ETag mismatch: the resource has been updated by another client."); } if (response.HttpStatusCode > 299) { this.log.Error("Unexpected error", () => new { this.storageName, Id = record.GetId(), ETag = record.GetETag(), response }); throw new ExternalDependencyException("Table storage request failed"); } return(true); } catch (CustomException) { throw; } catch (Exception e) { this.log.Error("Unexpected error while writing to Table Storage", () => new { this.storageName, id, ownerId, ownerType, e }); } return(false); }
public async Task <bool> TryToUnlockAsync(string id, string ownerId, string ownerType) { await this.SetupStorageAsync(); try { // Note: this can throw ResourceNotFoundException IDataRecord record = (await this.RetrieveAsync(id, true)).record; // Nothing to do if (!record.IsLocked()) { return(true); } if (!record.CanUnlock(ownerId, ownerType)) { this.log.Debug("The resource is locked by another client and cannot be unlocked by this client", () => new { this.storageName, id, ownerId, ownerType }); return(false); } record.Touch(); record.Unlock(ownerId, ownerType); await this.cosmosDbSql.UpsertAsync(this.cosmosDbSqlClient, this.storageConfig, (Resource)record); return(true); } catch (CustomException) { throw; } catch (DocumentClientException e) when(e.StatusCode == HttpStatusCode.PreconditionFailed) { this.log.Debug("ETag mismatch: the record has been updated by another client and cannot be unlocked.", () => new { this.storageName, id, ownerId, ownerType }); } catch (DocumentClientException e) when(e.StatusCode == HttpStatusCode.NotFound) { this.log.Warn("The record doesn't exist and cannot be unlocked", () => new { this.storageName, id, ownerId, ownerType }); } catch (Exception e) { const string MSG = "Unexpected error while writing to Cosmos DB SQL"; var errorData = new { this.storageName, id, ownerId, ownerType, e }; this.log.Error(MSG, () => errorData); this.diagnosticsLogger.LogServiceError(MSG, errorData); } return(false); }