// CloseShadow is called when the _real_ side is complete. This will cause // all future blocking operations to return immediately on the shadow to // ensure the shadow also completes. func (f *shadowComponentFactory) CloseShadow() error { // If we aren't the shadow, just return if !f.Shadow { return nil } // Lock ourselves so we don't modify state f.lock.Lock() defer f.lock.Unlock() // Grab our shared state shared := f.shadowComponentFactoryShared // If we're already closed, its an error if shared.closed { return fmt.Errorf("component factory shadow already closed") } // Close all the providers and provisioners and return the error var result error for _, n := range shared.providerKeys { _, shadow, err := shared.ResourceProvider(n, n) if err == nil && shadow != nil { if err := shadow.CloseShadow(); err != nil { result = multierror.Append(result, err) } } } for _, n := range shared.provisionerKeys { _, shadow, err := shared.ResourceProvisioner(n, n) if err == nil && shadow != nil { if err := shadow.CloseShadow(); err != nil { result = multierror.Append(result, err) } } } // Mark ourselves as closed shared.closed = true return result }
func (f *shadowComponentFactoryShared) ResourceProvisioner( n, uid string) (ResourceProvisioner, shadowResourceProvisioner, error) { // Determine if we already have a value raw, ok := f.provisioners.ValueOk(uid) if !ok { // Build the entry var entry shadowComponentFactoryProvisionerEntry // No value, initialize. Create the original p, err := f.contextComponentFactory.ResourceProvisioner(n, uid) if err != nil { entry.Err = err p = nil // Just to be sure } if p != nil { // For now, just create a mock since we don't support provisioners yet real, shadow := newShadowResourceProvisioner(p) entry.Real = real entry.Shadow = shadow if f.closed { shadow.CloseShadow() } } // Store the value f.provisioners.SetValue(uid, &entry) f.provisionerKeys = append(f.provisionerKeys, uid) raw = &entry } // Read the entry entry, ok := raw.(*shadowComponentFactoryProvisionerEntry) if !ok { return nil, nil, fmt.Errorf("Unknown value for shadow provisioner: %#v", raw) } // Return return entry.Real, entry.Shadow, entry.Err }