public async Task WriteContent(string name, byte[] content, long expectedStreamVersion, int retry = 0) { this.index = new FileIndexLock(storage, container, options.NamingPolicy.GetIndexPath(name)); try { //if (expectedStreamVersion == 0) //{ // await this.index.CreateIfNotExist(); // await this.masterindex.CreateIfNotExist(); //} var canWrite = await index.GetLeaseAndRead(expectedStreamVersion != 0); if (!canWrite) { if (retry < options.RetryPolicy.Length) { await Task.Delay(retry); await this.WriteContent(name, content, expectedStreamVersion, retry ++); return; } await this.index.CreateIfNotExist(); await this.index.ReadIndex(); throw new AppendOnlyTimeoutException(expectedStreamVersion, index.OrderedIndex.Any() ? this.index.ReadLast().Version : 0, name); } await this.index.ReadIndex(); var last = index.ReadLast(); if ((last == null && expectedStreamVersion != 0) || (last != null && expectedStreamVersion != last.Version) || (last != null && last.Version != expectedStreamVersion)) { throw new AppendOnlyStoreConcurrencyException(expectedStreamVersion, last?.Version ?? 0, name); } var blobcache = GetStreamCache(name); if (last == null) { //no file, create the stream to append to... await blobcache.CreateOrReplaceAsync(); } var master = this.GetMasterCache(); using (var memstream = new MemoryStream()) { var record = new FileRecord(content, name, expectedStreamVersion + 1); record.WriteContentToStream(memstream); var mybytes = memstream.ToArray(); var appendmaster = Task.Run(async() => { using (var masterstream = new MemoryStream(memstream.ToArray())) { await master.AppendBlockAsync(masterstream); } }); var up1 = blobcache.AppendFromByteArrayAsync(mybytes, 0, mybytes.Length); var up3 = index.AppendWrite(record, blobcache.Name); var up4 = masterindex.AppendWrite(record, blobcache.Name); await index.EnsureLease(); if (!options.DisableMasterIndex) { await Task.WhenAll(up1, appendmaster, up3); } else { await Task.WhenAll(up4, up1, appendmaster, up3); } } } finally { await index.Release(); } }
public async Task WriteContent(string name, byte[] content, long expectedStreamVersion, int retry = 0) { this.index = new FileIndexLock(storage, container, options.NamingPolicy.GetIndexPath(name)); try { //if (expectedStreamVersion == 0) //{ // await this.index.CreateIfNotExist(); // await this.masterindex.CreateIfNotExist(); //} var canWrite = await index.GetLeaseAndRead(expectedStreamVersion != 0); if (!canWrite) { if (retry < options.RetryPolicy.Length) { await Task.Delay(retry); await this.WriteContent(name, content, expectedStreamVersion, retry++); return; } await this.index.CreateIfNotExist(); await this.index.ReadIndex(); throw new AppendOnlyTimeoutException(expectedStreamVersion, index.OrderedIndex.Any() ? this.index.ReadLast().Version : 0, name); } await this.index.ReadIndex(); var last = index.ReadLast(); if ((last == null && expectedStreamVersion != 0) || (last != null && expectedStreamVersion != last.Version) || (last != null && last.Version != expectedStreamVersion )) { throw new AppendOnlyStoreConcurrencyException(expectedStreamVersion, last?.Version ?? 0, name); } var blobcache = GetStreamCache(name); if (last == null) { //no file, create the stream to append to... await blobcache.CreateOrReplaceAsync(); } var master = this.GetMasterCache(); using (var memstream = new MemoryStream()) { var record = new FileRecord(content, name, expectedStreamVersion + 1); record.WriteContentToStream(memstream); var mybytes = memstream.ToArray(); var appendmaster = Task.Run(async () => { using (var masterstream = new MemoryStream(memstream.ToArray())) { await master.AppendBlockAsync(masterstream); } }); var up1 = blobcache.AppendFromByteArrayAsync(mybytes, 0, mybytes.Length); var up3 = index.AppendWrite(record, blobcache.Name); var up4 = masterindex.AppendWrite(record, blobcache.Name); await index.EnsureLease(); if (!options.DisableMasterIndex) { await Task.WhenAll(up1, appendmaster, up3); } else { await Task.WhenAll(up4, up1, appendmaster, up3); } } } finally { await index.Release(); } }