public Result <string> TryAcquireLease(string containerName, string blobName) { var path = Path.Combine(_root, containerName, blobName); try { var file = new FileInfo(path); if (!file.Exists) { return(null); } using (var stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None)) using (var epStream = new MetadataPrefixStream(stream)) { var flags = epStream.ReadFlags(); if ((flags & 0x1) == 0x1) { // already locked, conflict return(Result <string> .CreateError("Conflict")); } epStream.WriteFlags((byte)(flags | 0x1)); return(Result.CreateSuccess(epStream.ReadETag())); } } catch (FileNotFoundException) { return(Result <string> .CreateError("NotFound")); } catch (DirectoryNotFoundException) { return(Result <string> .CreateError("NotFound")); } }
public string GetBlobEtag(string containerName, string blobName) { var path = Path.Combine(_root, containerName, blobName); try { var file = new FileInfo(path); if (!file.Exists) { return(null); } using (var stream = file.OpenRead()) using (var epStream = new MetadataPrefixStream(stream)) { return(epStream.ReadETag()); } } catch (FileNotFoundException) { return(null); } catch (DirectoryNotFoundException) { return(null); } }
public Maybe <object> GetBlob(string containerName, string blobName, Type type, out string etag, IDataSerializer serializer = null) { var path = Path.Combine(_root, containerName, blobName); try { var file = new FileInfo(path); if (!file.Exists) { etag = null; return(Maybe <object> .Empty); } using (var stream = file.OpenRead()) using (var epStream = new MetadataPrefixStream(stream)) { etag = epStream.ReadETag(); var deserialized = (serializer ?? _defaultSerializer).TryDeserialize(epStream, type); return(deserialized.IsSuccess ? new Maybe <object>(deserialized.Value) : Maybe <object> .Empty); } } catch (FileNotFoundException) { etag = null; return(Maybe <object> .Empty); } catch (DirectoryNotFoundException) { etag = null; return(Maybe <object> .Empty); } }
public Maybe <Stream> GetBlobStream(string containerName, string blobName, out string etag) { var path = Path.Combine(_root, containerName, blobName); try { var file = new FileInfo(path); if (!file.Exists) { etag = null; return(Maybe <Stream> .Empty); } using (var stream = file.OpenRead()) using (var epStream = new MetadataPrefixStream(stream)) { etag = epStream.ReadETag(); int length = (int)epStream.Length; epStream.Seek(0, SeekOrigin.Begin); var returnStream = new MemoryStream(length); byte[] buffer = new byte[8192]; int bytesRead = 1; while (length > 0 && bytesRead > 0) { bytesRead = epStream.Read(buffer, 0, Math.Min(length, buffer.Length)); returnStream.Write(buffer, 0, bytesRead); length -= bytesRead; } returnStream.Position = 0; return(new Maybe <Stream>(returnStream)); } } catch (FileNotFoundException) { etag = null; return(Maybe <Stream> .Empty); } catch (DirectoryNotFoundException) { etag = null; return(Maybe <Stream> .Empty); } }
public Result <string> TryRenewLease(string containerName, string blobName, string leaseId) { var path = Path.Combine(_root, containerName, blobName); try { var file = new FileInfo(path); if (!file.Exists) { return(null); } using (var stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None)) using (var epStream = new MetadataPrefixStream(stream)) { var flags = epStream.ReadFlags(); if ((flags & 0x1) == 0x0) { // not locked return(Result <string> .CreateError("NotFound")); } if (leaseId != epStream.ReadETag()) { // locked by another leaseId, conflict return(Result <string> .CreateError("Conflict")); } return(Result.CreateSuccess("OK")); } } catch (FileNotFoundException) { return(Result <string> .CreateError("NotFound")); } catch (DirectoryNotFoundException) { return(Result <string> .CreateError("NotFound")); } }
public Maybe <XElement> GetBlobXml(string containerName, string blobName, out string etag, IDataSerializer serializer = null) { var formatter = (serializer ?? _defaultSerializer) as IIntermediateDataSerializer; if (formatter == null) { etag = null; return(Maybe <XElement> .Empty); } var path = Path.Combine(_root, containerName, blobName); try { var file = new FileInfo(path); if (!file.Exists) { etag = null; return(Maybe <XElement> .Empty); } using (var stream = file.OpenRead()) using (var epStream = new MetadataPrefixStream(stream)) { etag = epStream.ReadETag(); var unpacked = formatter.TryUnpackXml(epStream); return(unpacked.IsSuccess ? new Maybe <XElement>(unpacked.Value) : Maybe <XElement> .Empty); } } catch (FileNotFoundException) { etag = null; return(Maybe <XElement> .Empty); } catch (DirectoryNotFoundException) { etag = null; return(Maybe <XElement> .Empty); } }
bool PutBlob(string containerName, string blobName, object item, Type type, bool overwrite, string expectedEtag, out string etag, IDataSerializer serializer = null) { var path = Path.Combine(_root, containerName, blobName); var folder = Path.GetDirectoryName(path); if (folder != null && !Directory.Exists(folder)) { Directory.CreateDirectory(folder); } var file = new FileInfo(path); if (overwrite) { // retry in case it is currently locked by another operation var optimisticPolicy = _policies.OptimisticConcurrency(); int retryCount = 0; while (true) { try { using (var stream = file.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)) using (var epStream = new MetadataPrefixStream(stream)) { if (!string.IsNullOrEmpty(expectedEtag) && epStream.ReadETag() != expectedEtag) { etag = null; return(false); } etag = WriteToStream(epStream, item, type, serializer); } return(true); } catch (IOException exception) { TimeSpan retryInterval; if (!optimisticPolicy.ShouldRetry(retryCount++, 0, exception, out retryInterval, null)) { throw; } // Retry Thread.Sleep(retryInterval); } } } // no need to retry in the non-overwrite case, since being locked implies the file already exist anyway try { using (var stream = file.Open(FileMode.CreateNew, FileAccess.Write, FileShare.None)) using (var epStream = new MetadataPrefixStream(stream)) { etag = WriteToStream(epStream, item, type, serializer); } return(true); } catch (IOException) { etag = null; return(false); } }