Exemple #1
0
        public TEntity AddOrUpdate(TKey key, Func <TEntity> addViewFactory, Func <TEntity, TEntity> updateViewFactory,
                                   AddOrUpdateHint hint)
        {
            string  etag = null;
            var     blob = GetBlobReference(key);
            TEntity view;

            try
            {
                // atomic entities should be small, so we can use the simple method
                var bytes = blob.DownloadByteArray();
                using (var stream = new MemoryStream(bytes))
                {
                    view = _strategy.Deserialize <TEntity>(stream);
                }

                view = updateViewFactory(view);
                etag = blob.Attributes.Properties.ETag;
            }
            catch (StorageClientException ex)
            {
                switch (ex.ErrorCode)
                {
                case StorageErrorCode.ContainerNotFound:
                    var s = string.Format(
                        "Container '{0}' does not exist. You need to initialize this atomic storage and ensure that '{1}' is known to '{2}'.",
                        blob.Container.Name, typeof(TEntity).Name, _strategy.GetType().Name);
                    throw new InvalidOperationException(s, ex);

                case StorageErrorCode.BlobNotFound:
                case StorageErrorCode.ResourceNotFound:
                    view = addViewFactory();
                    break;

                default:
                    throw;
                }
            }
            // atomic entities should be small, so we can use the simple method
            // http://toolheaven.net/post/Azure-and-blob-write-performance.aspx
            using (var memory = new MemoryStream())
            {
                _strategy.Serialize(view, memory);
                // note that upload from stream does weird things
                var bro = etag != null
                    ? new BlobRequestOptions {
                    AccessCondition = AccessCondition.IfMatch(etag)
                }
                    : new BlobRequestOptions {
                    AccessCondition = AccessCondition.IfNoneMatch("*")
                };


                // make sure that upload is not rejected due to cashed content MD5
                // http://social.msdn.microsoft.com/Forums/hu-HU/windowsazuredata/thread/4764e38f-b200-4efe-ada2-7de442dc4452
                blob.Properties.ContentMD5 = null;
                blob.UploadByteArray(memory.ToArray(), bro);
            }
            return(view);
        }
 public AutoRenewLease(CloudBlob blob)
 {
     this.blob = blob;
     blob.Container.CreateIfNotExist();
     try
     {
         blob.UploadByteArray(new byte[0], new BlobRequestOptions {
             AccessCondition = AccessCondition.IfNoneMatch("*")
         });
     }
     catch (StorageClientException e)
     {
         if (e.ErrorCode != StorageErrorCode.BlobAlreadyExists &&
             e.StatusCode != HttpStatusCode.PreconditionFailed)    // 412 from trying to modify a blob that's leased
         {
             throw;
         }
     }
     leaseId = blob.TryAcquireLease();
     if (HasLease)
     {
         renewalThread = new Thread(() =>
         {
             while (true)
             {
                 Thread.Sleep(TimeSpan.FromSeconds(40));
                 blob.RenewLease(leaseId);
             }
         });
         renewalThread.Start();
     }
 }
Exemple #3
0
        private BlobRequestOptions CreateBlobRequestOptions()
        {
            var etag    = this.Properties.ETag;
            var options = new BlobRequestOptions();

            options.AccessCondition = etag == null?
                                      AccessCondition.IfNoneMatch("*") :
                                          AccessCondition.IfMatch(etag);

            return(options);
        }
Exemple #4
0
        public AutoRenewLease(ILoggerFactory loggerFactory, LoggerLevel logLevel, CloudBlob blob, int renewLeaseSeconds = 40, int leaseLengthSeconds = 90)
        {
            _logger = loggerFactory.Create(GetType(), logLevel);
            var autoRenewLease = this;

            _blob = blob;
            blob.Container.CreateIfNotExist();
            try
            {
                blob.UploadByteArray(new byte[0], new BlobRequestOptions {
                    AccessCondition = AccessCondition.IfNoneMatch("*")
                });
            }
            catch (StorageClientException ex)
            {
                if (ex.ErrorCode != StorageErrorCode.BlobAlreadyExists)
                {
                    if (ex.StatusCode != HttpStatusCode.PreconditionFailed)
                    {
                        throw;
                    }
                }
            }
            LeaseId = blob.TryAcquireLease(leaseLengthSeconds);
            if (!HasLease)
            {
                return;
            }
            _cancellationTokenSource = new CancellationTokenSource();
            _resetEvent = new ManualResetEvent(false);
            Task.Factory.StartNew(() =>
            {
                try
                {
                    while (true)
                    {
                        _resetEvent.WaitOne(TimeSpan.FromSeconds(renewLeaseSeconds));
                        if (_cancellationTokenSource.IsCancellationRequested)
                        {
                            break;
                        }

                        blob.RenewLease(autoRenewLease.LeaseId);
                    }
                }
                catch (Exception e)
                {
                    LeaseId = null; // Release the lease
                    _logger.Error("Error renewing blob lease", e);
                }
            }, _cancellationTokenSource.Token);
        }
Exemple #5
0
 private static void CreateIfNotExist(this CloudBlob blob)
 {
     try
     {
         blob.UploadByteArray(new byte[0], new BlobRequestOptions {
             AccessCondition = AccessCondition.IfNoneMatch("*")
         });
     }
     catch (StorageClientException ex)
     {
         if (ex.ErrorCode != StorageErrorCode.BlobAlreadyExists && ex.StatusCode != HttpStatusCode.PreconditionFailed)
         {
             throw;
         }
     }
 }
        public static AutoRenewLease GetOrThrow(CloudBlob blob)
        {
            blob.Container.CreateIfNotExist();

            // Create lock blob
            try
            {
                var requestOptions = new BlobRequestOptions
                {
                    AccessCondition = AccessCondition.IfNoneMatch("*")
                };
                blob.UploadByteArray(new byte[0], requestOptions);
            }
            catch (StorageClientException e)
            {
                if (e.ErrorCode != StorageErrorCode.BlobAlreadyExists &&
                    e.StatusCode != HttpStatusCode.PreconditionFailed)
                // 412 from trying to modify a blob that's leased
                {
                    throw;
                }
            }

            string leaseId = null;
            var    ex      = DoUntilTrue(Try4Times, CancellationToken.None, () =>
            {
                leaseId = AcquireLease(blob);
                return(!String.IsNullOrEmpty(leaseId));
            });

            if (ex != null)
            {
                throw new InvalidOperationException("Failed to get lease", ex);
            }

            // Either we get lease or throw timeout exception
            if (String.IsNullOrEmpty(leaseId))
            {
                throw new InvalidOperationException();
            }

            return(new AutoRenewLease(blob, leaseId));
        }
Exemple #7
0
        static AccessCondition MapCondition(StreamingCondition condition)
        {
            switch (condition.Type)
            {
            case StreamingConditionType.None:
                return(AccessCondition.None);

            case StreamingConditionType.IfMatch:
                var x = ExposeException(condition.ETag, "'ETag' should be present");
                return(AccessCondition.IfMatch(x));

            case StreamingConditionType.IfNoneMatch:
                var etag = ExposeException(condition.ETag, "'ETag' should be present");
                return(AccessCondition.IfNoneMatch(etag));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #8
0
        public bool SetIfNotExists(T obj)
        {
            BlobRequestOptions reqOpt = new BlobRequestOptions();

            reqOpt.AccessCondition = AccessCondition.IfNoneMatch("*");
            try
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    Serializer.Serialize(stream, obj);
                    stream.Seek(0, SeekOrigin.Begin);
                    blob.UploadFromStream(stream, reqOpt);
                }
                return(true);
            }
            catch (StorageClientException e)
            {
                if (e.ErrorCode != StorageErrorCode.ConditionFailed && e.ErrorCode != StorageErrorCode.BlobAlreadyExists)
                {
                    throw;
                }
                return(false);
            }
        }