// Pass in data that was encrypted at rest // for upload to SAFENetwork. public async Task <(NetworkEvent, Result <Pointer>)> Upload(WALContent walContent) { var data = ZipEncryptedEvent.From(walContent.EncryptedContent); var localEvt = data.GetEvent(_pwd); var networkEvt = await GetNetworkEvent(localEvt); var expectedVersion = walContent.SequenceNr == 0 ? ExpectedVersion.None : ExpectedVersion.Specific(walContent.SequenceNr - 1); var result = await _stream.TryAppendAsync(new StoredValue(networkEvt), expectedVersion); return(networkEvt, result); }
// new data from network.. this effectively means we have a fork.. // can we implement merge rules? // Temporarily: only appending with new version nr at end. // this will very likely lead to corrupted stream if any real // concurrent usage of the drive occurs. // TODO: Needs A LOT of work. async Task <bool> TryMergeAsync(NetworkEvent evt, WALContent walContent) { var newData = await _service .LoadAsync(evt.SequenceNr - 1) .ToListAsync(); switch (evt) { case NetworkFileContentSet e when IsUnresolvableConflict(e, newData): return(false); case NetworkFileItemCreated e: break; case NetworkFileContentCleared e: break; case NetworkItemCopied e: break; case NetworkItemMoved e: break; case NetworkDirectoryItemCreated e: break; case NetworkItemRemoved e: break; case NetworkItemRenamed e: break; case null: throw new ArgumentNullException(nameof(evt)); default: throw new NotImplementedException(evt.GetType().Name); } // naively just try apply the remote changes var caughtUp = await _materializer.Materialize(newData.ToAsyncEnumerable()); if (!caughtUp) { return(false); } walContent.SequenceNr = newData.Max(c => c.SequenceNr) + 1; return(await Upload(walContent)); }
public async Task <bool> Upload(WALContent walContent) { var(e, result) = await _service.Upload(walContent); switch (result) { case VersionMismatch <Pointer> mismatch: return(await TryMergeAsync(e, walContent)); case var r when r.HasValue: return(r.HasValue); default: return(result.HasValue); } }