func (d *Data) putChunk(chunk *storage.Chunk, putbuffer storage.RequestBuffer) { defer func() { // After processing a chunk, return the token. server.HandlerToken <- 1 // Notify the requestor that this chunk is done. if chunk.Wg != nil { chunk.Wg.Done() } }() op, ok := chunk.Op.(*putOperation) if !ok { log.Fatalf("Illegal operation passed to ProcessChunk() for data %s\n", d.DataName()) } // Make sure our received chunk is valid. if chunk == nil { dvid.Errorf("Received nil chunk in ProcessChunk. Ignoring chunk.\n") return } if chunk.K == nil { dvid.Errorf("Received nil chunk key in ProcessChunk. Ignoring chunk.\n") return } // Initialize the block buffer using the chunk of data. For voxels, this chunk of // data needs to be uncompressed and deserialized. var blockData []byte var err error if chunk.V == nil { blockData = d.BackgroundBlock() } else { blockData, _, err = dvid.DeserializeData(chunk.V, true) if err != nil { dvid.Errorf("Unable to deserialize block in %q: %v\n", d.DataName(), err) return } } // If we are mutating, get the previous block of data. var oldBlock []byte if op.mutate { oldBlock, err = d.loadOldBlock(op.version, chunk.K) if err != nil { dvid.Errorf("Unable to load previous block in %q, key %v: %v\n", d.DataName(), chunk.K, err) return } } // Perform the operation. block := &storage.TKeyValue{K: chunk.K, V: blockData} if err = op.voxels.WriteBlock(block, d.BlockSize()); err != nil { dvid.Errorf("Unable to WriteBlock() in %q: %v\n", d.DataName(), err) return } serialization, err := dvid.SerializeData(blockData, d.Compression(), d.Checksum()) if err != nil { dvid.Errorf("Unable to serialize block in %q: %v\n", d.DataName(), err) return } store, err := d.GetOrderedKeyValueDB() if err != nil { dvid.Errorf("Data type imageblk had error initializing store: %v\n", err) return } ready := make(chan error, 1) callback := func() { // Notify any subscribers that you've changed block. resperr := <-ready if resperr != nil { dvid.Errorf("Unable to PUT voxel data for key %v: %v\n", chunk.K, resperr) return } var event string var delta interface{} if op.mutate { event = MutateBlockEvent delta = MutatedBlock{&op.indexZYX, oldBlock, block.V, op.mutID} } else { event = IngestBlockEvent delta = Block{&op.indexZYX, block.V, op.mutID} } evt := datastore.SyncEvent{d.DataUUID(), event} msg := datastore.SyncMessage{event, op.version, delta} if err := datastore.NotifySubscribers(evt, msg); err != nil { dvid.Errorf("Unable to notify subscribers of event %s in %s\n", event, d.DataName()) } } // put data -- use buffer if available ctx := datastore.NewVersionedCtx(d, op.version) if putbuffer != nil { go callback() putbuffer.PutCallback(ctx, chunk.K, serialization, ready) } else { if err := store.Put(ctx, chunk.K, serialization); err != nil { dvid.Errorf("Unable to PUT voxel data for key %v: %v\n", chunk.K, err) return } ready <- nil callback() } }