/// <inheritdoc /> public async Task <MachineStatus <TState, TInput> > CreateMachineAsync( Schematic <TState, TInput> schematic, string machineId, Metadata metadata, CancellationToken cancellationToken = default) { if (schematic == null) { throw new ArgumentNullException(nameof(schematic)); } var id = machineId ?? Guid.NewGuid().ToString(); var schematicBytes = LZ4MessagePackSerializer.Serialize(schematic, ContractlessStandardResolver.Instance); var hash = Convert.ToBase64String(Murmur3.ComputeHashBytes(schematicBytes)); var schematicResult = await _restateDatabase.StringGetAsync($"{MachineSchematicsKeyPrefix}/{hash}"); if (!schematicResult.HasValue) { await _restateDatabase.StringSetAsync($"{MachineSchematicsKeyPrefix}/{hash}", schematicBytes); } const int commitNumber = 0; var updatedTime = DateTimeOffset.UtcNow; var record = new RedisMachineStatus <TState, TInput> { MachineId = id, SchematicHash = hash, State = schematic.InitialState, CommitNumber = commitNumber, UpdatedTime = updatedTime, Metadata = metadata, StateBag = new Dictionary <string, string>() }; var recordBytes = MessagePackSerializer.Serialize(record); await _restateDatabase.StringSetAsync($"{MachinesKeyPrefix}/{machineId}", recordBytes, null, When.NotExists).ConfigureAwait(false); return(new MachineStatus <TState, TInput> { MachineId = machineId, Schematic = schematic, State = schematic.InitialState, CommitNumber = commitNumber, UpdatedTime = updatedTime, Metadata = metadata, StateBag = record.StateBag }); }
/// <inheritdoc /> public async Task <ICollection <MachineStatus <TState, TInput> > > BulkCreateMachinesAsync( Schematic <TState, TInput> schematic, IEnumerable <Metadata> metadata, CancellationToken cancellationToken = default) { var schematicBytes = LZ4MessagePackSerializer.Serialize(schematic, ContractlessStandardResolver.Instance); var hash = Convert.ToBase64String(Murmur3.ComputeHashBytes(schematicBytes)); const int commitNumber = 0; var machineRecords = metadata.Select(meta => new MachineStatus <TState, TInput> { MachineId = Guid.NewGuid().ToString(), Schematic = schematic, State = schematic.InitialState, CommitNumber = commitNumber, UpdatedTime = DateTime.UtcNow, Metadata = meta, StateBag = new Dictionary <string, string>() }).ToList(); await _restateDatabase.StringSetAsync($"{MachineSchematicsKeyPrefix}/{hash}", schematicBytes, null, When.NotExists); var batchOps = machineRecords.Select(s => _restateDatabase.StringSetAsync($"{MachinesKeyPrefix}/{s.MachineId}", MessagePackSerializer.Serialize( new RedisMachineStatus <TState, TInput> { MachineId = s.MachineId, SchematicHash = hash, State = s.State, CommitNumber = s.CommitNumber, UpdatedTime = s.UpdatedTime, Metadata = s.Metadata, StateBag = s.StateBag })) ); await Task.WhenAll(batchOps).ConfigureAwait(false); return(machineRecords); }