code: func (b *backend) updateSink(oldSink, newSink *auditregv1alpha1.AuditSink) {
  	b.delegateUpdateMutex.Lock()
  	defer b.delegateUpdateMutex.Unlock()
  	delegates := b.copyDelegates()
  	oldDelegate, ok := delegates[oldSink.UID]
  	if !ok {
  		klog.Errorf("Could not update audit sink %q uid: %s, old sink does not exist",
  			oldSink.Name, oldSink.UID)
  		return
  	}
  
  	// check if spec has changed
  	eq := reflect.DeepEqual(oldSink.Spec, newSink.Spec)
  	if eq {
  		delete(delegates, oldSink.UID)
  		delegates[newSink.UID] = oldDelegate
  		b.setDelegates(delegates)
  	} else {
  		d, err := b.createAndStartDelegate(newSink)
  		if err != nil {
  			msg := fmt.Sprintf("Could not update audit sink %q: %v", oldSink.Name, err)
  			klog.Error(msg)
  			b.recorder.Event(newSink, corev1.EventTypeWarning, "UpdateFailed", msg)
  			return
  		}
  		delete(delegates, oldSink.UID)
  		delegates[newSink.UID] = d
  		b.setDelegates(delegates)
  
  		// graceful shutdown in goroutine as to not block
  		go oldDelegate.gracefulShutdown()
  	}
  
  	klog.V(2).Infof("Updated audit sink: %s", newSink.Name)
  	klog.V(2).Infof("Current audit sinks: %v", delegates.Names())
  }
docs: // updateSink is called by the shared informer when a sink is updated.
  // The new sink is only rebuilt on spec changes. The new sink must not have
  // the same uid as the previous. The new sink will be started before the old
  // one is shutdown so no events will be lost