/// <summary> /// Write a data item into data container and flush /// </summary> /// <param name="data">data content to be written</param> public void AddDataAndFlush(DataContent data) { TraceHelper.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "[ComplexDataContainer] .AddDataAndFlush"); CountdownEvent doneEvent = new CountdownEvent(this.secondaryContainers.Count); foreach (IDataContainer secondaryContainer in this.secondaryContainers) { ThreadPool.QueueUserWorkItem( delegate { try { secondaryContainer.AddDataAndFlush(data); } catch (Exception ex) { // do not throw exception for secondary containers TraceHelper.TraceSource.TraceEvent(TraceEventType.Error, 0, "[ComplexDataContainer] .AddDataAndFlush: container {0} receives exception = {1}", secondaryContainer.Id, ex); } finally { doneEvent.Signal(); } }); } Exception exception = null; try { this.primaryContainer.AddDataAndFlush(data); } catch (DataException ex) { exception = ex; } doneEvent.Wait(); // if the primary container is in problem, or is deleted, delete the secondary containers if (exception != null || !this.primaryContainer.Exists()) { foreach (IDataContainer secondaryContainer in this.secondaryContainers) { try { secondaryContainer.DeleteIfExists(); } catch (Exception ex) { TraceHelper.TraceSource.TraceEvent(TraceEventType.Error, 0, "[ComplexDataContainer] .AddDataAndFlush: delete container {0} receives exception = {1}", secondaryContainer.Id, ex); } } } }
/// <summary> /// Creates a RawBytesDataContent instance from byte array /// </summary> /// <param name="contentBytes">data content in byte array</param> /// <returns>new created RawBytesDataContent instance</returns> public static RawBytesDataContent Parse(byte[] contentBytes) { if (DataContent.IsCompressed(contentBytes)) { TraceHelper.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "[DataClient] .RawBytesDataContent.Parse: data is compressed"); MemoryStream inStream = null; try { inStream = new MemoryStream(contentBytes); using (MemoryStream outStream = new MemoryStream()) { inStream.Seek(DataContent.HeaderLength, SeekOrigin.Begin); using (GZipStream gzs = new GZipStream(inStream, CompressionMode.Decompress)) { inStream = null; const int BufferSize = 4096; byte[] buffer = new byte[BufferSize]; while (true) { int bytesRead = gzs.Read(buffer, 0, BufferSize); if (bytesRead <= 0) { break; } outStream.Write(buffer, 0, bytesRead); } return(new RawBytesDataContent(outStream.ToArray(), true)); } } } finally { if (inStream != null) { inStream.Dispose(); } } } else { return(new RawBytesDataContent(contentBytes, false)); } }
/// <summary> /// Write a data item into data container and flush /// </summary> /// <param name="data">data content to be written</param> public void AddDataAndFlush(DataContent data) { throw new NotSupportedException(); }
/// <summary> /// Write a data item into data container and flush /// </summary> /// <param name="data">data content to be written</param> public void AddDataAndFlush(DataContent data) { TraceHelper.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "[FileDataContainer] .AddDataAndFlush"); int retryCount = 0; int retryCountForNetNameDeleted = 0; while (true) { try { // write data using (FileStream fs = new FileStream(this.filePath, FileMode.Open, FileAccess.Write, FileShare.Read | FileShare.Delete, bufferSize)) { this.accessFlag = true; // write data item data.Dump(fs); } return; } catch (IOException e) { int errorCode = GetIOErrorCode(e); if (errorCode == FileNativeMethods.ErrorFileNotFound) { // Bug 14480: FileNotFoundException may be thrown because of SMB2.0 client redirector cache. if (this.accessFlag || isSMB2ClientFileNotFoundCacheDisabled || retryCount >= FileNotFoundExceptionRetryLimit) { throw new DataException(DataErrorCode.DataClientDeleted, e); } Thread.Sleep(FileNotFoundExceptionRetryPeriod); retryCount++; } else if (errorCode == FileNativeMethods.ErrorNetNameDeleted && retryCountForNetNameDeleted < MaxRetryCount) { // Bug 14068: ERROR_NETNAME_DELETED error may occur. As it is intermediate, fix it by retry Thread.Sleep(NetNameDeletedExceptionRetryPeriod); retryCountForNetNameDeleted++; } else { int dataErrorCode = GetDataErrorCode(e); throw new DataException(dataErrorCode, e); } } catch (SecurityException e) { throw new SecurityException(SR.DataNoPermission, e); } catch (UnauthorizedAccessException e) { throw new UnauthorizedAccessException(SR.DataNoPermission, e); } catch (SerializationException) { throw; } catch (DataException) { throw; } catch (Exception e) { throw new DataException(DataErrorCode.Unknown, e); } } }
/// <summary> /// Write a data item into data container and flush /// </summary> /// <param name="data">data content to be written</param> public void AddDataAndFlush(DataContent data) { TraceHelper.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "[BlobDataContainer] .AddDataAndFlush"); using (MemoryStream ms = new MemoryStream()) { // dump all data into a memory stream data.Dump(ms); // create timer that updates "CommonDataLastUpdateTime" metadata peoriodically Timer updateMetadataTimer = new Timer( this.MarkBlobAsBeingUploaded, null, TimeSpan.FromMilliseconds(Constant.LastUpdateTimeUpdateIntervalInMilliseconds), TimeSpan.FromMilliseconds(Constant.LastUpdateTimeUpdateIntervalInMilliseconds)); // write data Exception transferException = null; try { BlobTransferOptions transferOptions = new BlobTransferOptions { Concurrency = Environment.ProcessorCount * 8, }; using (BlobTransferManager transferManager = new BlobTransferManager(transferOptions)) { transferManager.QueueUpload( this.dataBlob, ms, null, delegate(object userData, double speed, double progress) { TraceHelper.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "[BlobDataContainer] .AddDataAndFlush: progress={0}%", progress); }, delegate(object userData, Exception ex) { if (ex != null) { transferException = ex; } }, null); transferManager.WaitForCompletion(); } } finally { updateMetadataTimer.Dispose(); } TraceHelper.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "[BlobDataContainer] .AddDataAndFlush: data transfer done"); DataException dataException = null; if (transferException != null) { dataException = TranslateTransferExceptionToDataException(transferException); } try { int errorCode = DataErrorCode.Success; string errorMessage = string.Empty; if (dataException != null) { errorCode = dataException.ErrorCode; errorMessage = dataException.Message; } AzureBlobHelper.MarkBlobAsCompleted(this.dataBlob, errorCode.ToString(), errorMessage); } catch (StorageException ex) { TraceHelper.TraceSource.TraceEvent( TraceEventType.Error, 0, "[BlobDataContainer] .AddDataAndFlush: failed to mark blob as completed. blob url={0}. error code={1}, exception={2}", this.dataBlob.Uri.AbsoluteUri, BurstUtility.GetStorageErrorCode(ex), ex); } catch (Exception ex) { TraceHelper.TraceSource.TraceEvent( TraceEventType.Error, 0, "[BlobDataContainer] .AddDataAndFlush: failed to mark blob as completed. blob url={0}. Exception={1}", this.dataBlob.Uri.AbsoluteUri, ex); } if (dataException != null) { throw dataException; } } }