09/17/2018, 11:16 PM
here's my version of RegisterResourceOutputs:
// RegisterResourceOutputs completes the resource registration, attaching an optional set of computed outputs.
func (ctx *Context) RegisterResourceOutputs(urn URN, outs map[string]interface{}) error {

	_, outsMarshalled, _, err := marshalInputs(outs)
	if err != nil {
		return errors.Wrap(err, "marshaling arguments")

	// Note that we're about to make an outstanding RPC request, so that we can rendezvous during shutdown.
	if err = ctx.beginRPC(); err != nil {
		return err

	// Kick off the resource registration.  If we are actually performing a deployment, the resulting properties
	// will be resolved asynchronously as the RPC operation completes.  If we're just planning, values won't resolve.
	go func() {
		glog.V(9).Infof("RegisterResourceOutputs(%s): Goroutine spawned, RPC call being made", urn)
		_, err := ctx.monitor.RegisterResourceOutputs(ctx.ctx, &pulumirpc.RegisterResourceOutputsRequest{
			Urn:     string(urn),
			Outputs: outsMarshalled,
		if err != nil {
			glog.V(9).Infof("RegisterResource(%s): error: %v", urn, err)
		} else {
			glog.V(9).Infof("RegisterResource(%s): success: %s %s ...", urn)

		// Signal the completion of this RPC and notify any potential awaiters.
	return nil