// GetSyncSubs implements the datastore.Syncer interface func (d *Data) GetSyncSubs(synced dvid.Data) (datastore.SyncSubs, error) { if d.syncCh == nil { if err := d.InitDataHandlers(); err != nil { return nil, fmt.Errorf("unable to initialize handlers for data %q: %v\n", d.DataName(), err) } } var evts []string switch synced.TypeName() { case "labelblk": // For down-res support evts = []string{ DownsizeBlockEvent, DownsizeCommitEvent, labels.IngestBlockEvent, labels.MutateBlockEvent, labels.DeleteBlockEvent, } case "labelvol": evts = []string{labels.MergeBlockEvent, labels.SplitLabelEvent} default: return nil, fmt.Errorf("Unable to sync %s with %s since datatype %q is not supported.", d.DataName(), synced.DataName(), synced.TypeName()) } subs := make(datastore.SyncSubs, len(evts)) for i, evt := range evts { subs[i] = datastore.SyncSub{ Event: datastore.SyncEvent{synced.DataUUID(), evt}, Notify: d.DataUUID(), Ch: d.syncCh, } } return subs, nil }
// StartInstancePush initiates a data instance push. After some number of Send // calls, the EndInstancePush must be called. func (p *PushSession) StartInstancePush(d dvid.Data) error { dmsg := DataTxInit{ Session: p.s.ID(), DataName: d.DataName(), TypeName: d.TypeName(), InstanceID: d.InstanceID(), } if _, err := p.s.Call()(StartDataMsg, dmsg); err != nil { return fmt.Errorf("couldn't send data instance %q start: %v\n", d.DataName(), err) } return nil }
// GetSyncSubs implements the datastore.Syncer interface. Returns a list of subscriptions // to the sync data instance that will notify the receiver. func (d *Data) GetSyncSubs(synced dvid.Data) (subs datastore.SyncSubs, err error) { if d.syncCh == nil { if err = d.InitDataHandlers(); err != nil { err = fmt.Errorf("unable to initialize handlers for data %q: %v\n", d.DataName(), err) return } } // Our syncing depends on the datatype we are syncing. switch synced.TypeName() { case "labelblk": subs = datastore.SyncSubs{ { Event: datastore.SyncEvent{synced.DataUUID(), labels.IngestBlockEvent}, Notify: d.DataUUID(), Ch: d.syncCh, }, { Event: datastore.SyncEvent{synced.DataUUID(), labels.MutateBlockEvent}, Notify: d.DataUUID(), Ch: d.syncCh, }, { Event: datastore.SyncEvent{synced.DataUUID(), labels.DeleteBlockEvent}, Notify: d.DataUUID(), Ch: d.syncCh, }, } case "labelvol": subs = datastore.SyncSubs{ datastore.SyncSub{ Event: datastore.SyncEvent{synced.DataUUID(), labels.MergeBlockEvent}, Notify: d.DataUUID(), Ch: d.syncCh, }, datastore.SyncSub{ Event: datastore.SyncEvent{synced.DataUUID(), labels.SplitLabelEvent}, Notify: d.DataUUID(), Ch: d.syncCh, }, } default: err = fmt.Errorf("Unable to sync %s with %s since datatype %q is not supported.", d.DataName(), synced.DataName(), synced.TypeName()) } return }
// DeleteDataInstance removes a data instance across all versions and tiers of storage. func DeleteDataInstance(data dvid.Data) error { if !manager.setup { return fmt.Errorf("Can't delete data instance %q before storage manager is initialized", data.DataName()) } // Determine all database tiers that are distinct. dbs := []OrderedKeyValueDB{manager.mutable} if manager.mutable != manager.immutable { dbs = append(dbs, manager.immutable) } // For each storage tier, remove all key-values with the given instance id. dvid.Infof("Starting delete of instance %d: name %q, type %s\n", data.InstanceID(), data.DataName(), data.TypeName()) ctx := NewDataContext(data, 0) for _, db := range dbs { if err := db.DeleteAll(ctx, true); err != nil { return err } } return nil }
// DeleteDataInstance removes a data instance. func DeleteDataInstance(data dvid.Data) error { if !manager.setup { return fmt.Errorf("Can't delete data instance %q before storage manager is initialized", data.DataName()) } // Get the store for the data instance. store, err := data.BackendStore() if err != nil { return err } db, ok := store.(OrderedKeyValueDB) if !ok { return fmt.Errorf("store assigned to data %q is not an ordered kv db with ability to delete all", data.DataName()) } dvid.Infof("Starting delete of instance %d: name %q, type %s\n", data.InstanceID(), data.DataName(), data.TypeName()) ctx := NewDataContext(data, 0) if err := db.DeleteAll(ctx, true); err != nil { return err } return nil }
// BadAPIRequest writes a standard error message to http.ResponseWriter for a badly formatted API call. func BadAPIRequest(w http.ResponseWriter, r *http.Request, d dvid.Data) { helpURL := path.Join("api", "help", string(d.TypeName())) msg := fmt.Sprintf("Bad API call (%s) for data %q. See API help at http://%s/%s", r.URL.Path, d.DataName(), GetConfig().Host(), helpURL) http.Error(w, msg, http.StatusBadRequest) dvid.Errorf("Bad API call (%s) for data %q\n", r.URL.Path, d.DataName()) }