Example #1
0
// 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
}
Example #2
0
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
}