code: func Shutdown(ctx context.Context) {
  	for {
  		tiPlugins := pluginGlobal.plugins()
  		if tiPlugins == nil {
  			return
  		}
  		for _, plugins := range tiPlugins.plugins {
  			for _, p := range plugins {
  				p.State = Dying
  				if p.flushWatcher != nil {
  					p.flushWatcher.cancel()
  				}
  				if err := p.OnShutdown(ctx, p.Manifest); err != nil {
  					logutil.Logger(ctx).Error("call OnShutdown for failure",
  						zap.String("plugin", p.Name), zap.Error(err))
  				}
  			}
  		}
  		if atomic.CompareAndSwapPointer(&pluginGlobal.tiPlugins, unsafe.Pointer(tiPlugins), nil) {
  			return
  		}
  	}
  }
docs: // Shutdown cleanups all plugin resources.
  // Notice: it just cleanups the resource of plugin, but cannot unload plugins(limited by go plugin).