public static Task <SagaStorageFile> Open(Guid sagaId, SagaManifest manifest, CancellationToken cancellationToken = default)
        {
            var filePath = manifest.GetFilePath(sagaId);

            if (!File.Exists(filePath))
            {
                return(noSagaFoundResult);
            }

            return(OpenWithRetryOnConcurrency(filePath, FileMode.Open, cancellationToken));
        }
        public static Task <SagaStorageFile> Open(Guid sagaId, SagaManifest manifest)
        {
            var filePath = manifest.GetFilePath(sagaId);

            if (!File.Exists(filePath))
            {
                return(noSagaFoundResult);
            }

            return(OpenWithDelayOnConcurrency(filePath, FileMode.Open));
        }
 SagaStorageFile(FileStream fileStream, SagaManifest manifest)
 {
     this.fileStream = fileStream;
     this.manifest   = manifest;
     jsonWriter      = new JsonTextWriter(new StreamWriter(fileStream, Encoding.Unicode))
     {
         CloseOutput = true,
         Formatting  = Formatting.Indented
     };
     jsonReader = new JsonTextReader(new StreamReader(fileStream, Encoding.Unicode))
     {
         CloseInput = true
     };
 }
        static async Task <SagaStorageFile> OpenWithDelayOnConcurrency(SagaManifest manifest, string filePath, FileMode fileAccess)
        {
            try
            {
                return(new SagaStorageFile(new FileStream(filePath, fileAccess, FileAccess.ReadWrite, FileShare.None, DefaultBufferSize, FileOptions.Asynchronous), manifest));
            }
            catch (IOException)
            {
                // give the other task some time to complete the saga to avoid retrying to much
                await Task.Delay(100)
                .ConfigureAwait(false);

                throw;
            }
        }
        public SagaManifestCollection(SagaMetadataCollection sagas, string storageLocation)
        {
            foreach (var metadata in sagas)
            {
                var sagaStorageDir = Path.Combine(storageLocation, metadata.SagaType.FullName.Replace("+", ""));

                if (!Directory.Exists(sagaStorageDir))
                {
                    Directory.CreateDirectory(sagaStorageDir);
                }

                var manifest = new SagaManifest
                {
                    StorageDirectory = sagaStorageDir,
                    SagaEntityType   = metadata.SagaEntityType
                };

                sagaManifests[metadata.SagaEntityType] = manifest;
            }
        }
        public SagaManifestCollection(SagaMetadataCollection sagas, string storageLocation, Func <string, string> sagaNameConverter)
        {
            foreach (var metadata in sagas)
            {
                var sagaStorageDir = Path.Combine(storageLocation, sagaNameConverter(metadata.SagaType.FullName));

                if (!Directory.Exists(sagaStorageDir))
                {
                    Directory.CreateDirectory(sagaStorageDir);
                }

                var manifest = new SagaManifest
                {
                    StorageDirectory = sagaStorageDir,
                    SagaEntityType   = metadata.SagaEntityType
                };

                sagaManifests[metadata.SagaEntityType] = manifest;
            }
        }
        public static Task <SagaStorageFile> Create(Guid sagaId, SagaManifest manifest)
        {
            var filePath = manifest.GetFilePath(sagaId);

            return(OpenWithDelayOnConcurrency(filePath, FileMode.CreateNew));
        }
        public static Task <SagaStorageFile> Create(Guid sagaId, SagaManifest manifest, CancellationToken cancellationToken = default)
        {
            var filePath = manifest.GetFilePath(sagaId);

            return(OpenWithRetryOnConcurrency(filePath, FileMode.CreateNew, cancellationToken));
        }