Ejemplo n.º 1
0
        public async Task <bool> TryLock()
        {
            try
            {
                _lease   = _blobLeaseFactory.CreateLease(_blob);
                _leaseId = await _lease.TryAcquireLease();

                if (_leaseId == null)
                {
                    DisposeLease();
                    return(false);
                }
                await _blob.FetchAttributesAsync();

                if (_blob.Metadata.ContainsKey(UpdateDomainInstancesKey))
                {
                    string[] instanceIds = _blob.Metadata[UpdateDomainInstancesKey].Split(',');
                    _instanceIds = new HashSet <string>(instanceIds);
                }
                _updateDomain = _blob.Metadata.ContainsKey(UpdateDomainKey) ? _blob.Metadata[UpdateDomainKey] : string.Empty;

                return(true);
            }
            catch (StorageException e)
            {
                DisposeLease();
                Trace.TraceInformation($"Failed to acquire the lease on blob {_blob.Name}", e);
                return(false);
            }
        }
        public async Task <bool> TryStartUpdateSession(string applicationId)
        {
            string updateBlobName = GetUpdateBlobName(applicationId);
            bool   started        = false;

            try
            {
                ICloudBlob updateBlob = GetBlob(updateBlobName);
                await CreateBlobIfNoneExists(updateBlob);

                IBlobLease blobLease = _blobLeaseFactory.CreateLease(updateBlob);

                ExceptionDispatchInfo capturedException = null;
                string leaseId = await blobLease.TryAcquireLease();

                // allow this instance to update only if it can acquire a lease on the blob.
                if (leaseId == null)
                {
                    Trace.TraceInformation("Cannot start update session because unable to acquire the lease on the blob");
                    return(false);
                }

                try
                {
                    var updateBlobWrapper = await UpdateBlobWrapper.Create(updateBlob);

                    var updateDomain = updateBlobWrapper.GetUpdateDomain();
                    HashSet <string> updateDomainInstancesHashset = updateBlobWrapper.GetInstanceIds();

                    // allow this instance to try updating only if either one of the following conditions are true:
                    // 1. no update domain is set,
                    // 2. the current instance is in the same update domain
                    // 3. no instances are set for the current update domain
                    if (string.IsNullOrEmpty(updateDomain) ||
                        _config.InstanceUpdateDomain == updateDomain ||
                        updateDomainInstancesHashset.Count == 0)
                    {
                        Trace.TraceInformation(
                            "Instance {0} acquired a lock on update blob {1} and will attempt to enlist itself",
                            _config.InstanceId, updateBlobName);

                        updateDomainInstancesHashset.Add(_config.InstanceId);
                        await
                        updateBlobWrapper.SetData(leaseId, _config.InstanceUpdateDomain,
                                                  updateDomainInstancesHashset);

                        Trace.TraceInformation("Instance {0} enlisted itself in the update blob", _config.InstanceId);
                        started = true;
                    }
                }
                catch (Exception e)
                {
                    capturedException = ExceptionDispatchInfo.Capture(e);
                }

                await blobLease.ReleaseLease();

                Trace.TraceInformation("Instance {0} released the lock on update blob {1}", _config.InstanceId, updateBlobName);

                if (capturedException != null)
                {
                    capturedException.Throw();
                }

                return(started);
            }
            catch (Exception ex)
            {
                throw new Exception("Failed to start update session ", ex);
            }
        }