github.com/bhameyie/otto@v0.2.1-0.20160406174117-16052efa52ec/rpc/context.go (about)

     1  package rpc
     2  
     3  import (
     4  	"io"
     5  	"log"
     6  	"net/rpc"
     7  
     8  	"github.com/hashicorp/otto/context"
     9  )
    10  
    11  // ContextSharedArgs is a struct that should be embedded directly into
    12  // args structs that contain a context. It will be populated with the IDs
    13  // that can be used to communicate back to the interfaces.
    14  type ContextSharedArgs struct {
    15  	DirectoryId uint32
    16  	UiId        uint32
    17  }
    18  
    19  func connectContext(
    20  	broker *muxBroker,
    21  	ctx *context.Shared, args *ContextSharedArgs) (io.Closer, error) {
    22  	closer := &multiCloser{}
    23  
    24  	// Setup Directory
    25  	conn, err := broker.Dial(args.DirectoryId)
    26  	if err != nil {
    27  		return closer, err
    28  	}
    29  	client := rpc.NewClient(conn)
    30  	closer.Closers = append(closer.Closers, client)
    31  	ctx.Directory = &Directory{
    32  		Broker: broker,
    33  		Client: client,
    34  		Name:   "Directory",
    35  	}
    36  
    37  	// Setup Ui
    38  	conn, err = broker.Dial(args.UiId)
    39  	if err != nil {
    40  		return closer, err
    41  	}
    42  	client = rpc.NewClient(conn)
    43  	closer.Closers = append(closer.Closers, client)
    44  	ctx.Ui = &Ui{
    45  		Client: client,
    46  		Name:   "Ui",
    47  	}
    48  
    49  	return closer, nil
    50  }
    51  
    52  func serveContext(broker *muxBroker, ctx *context.Shared, args *ContextSharedArgs) {
    53  	// Serve the directory
    54  	id := broker.NextId()
    55  	go acceptAndServe(broker, id, "Directory", &DirectoryServer{
    56  		Broker:    broker,
    57  		Directory: ctx.Directory,
    58  	})
    59  	args.DirectoryId = id
    60  
    61  	// Server the Ui
    62  	id = broker.NextId()
    63  	go acceptAndServe(broker, id, "Ui", &UiServer{
    64  		Ui: ctx.Ui,
    65  	})
    66  	args.UiId = id
    67  
    68  	// Set the context fields to nil so that they aren't sent over the
    69  	// network (Go will just panic if we didn't do this).
    70  	ctx.Directory = nil
    71  	ctx.Ui = nil
    72  }
    73  
    74  // multiCloser is an io.Closer that closes multiple closers.
    75  type multiCloser struct {
    76  	Closers []io.Closer
    77  }
    78  
    79  func (c *multiCloser) Close() error {
    80  	for _, single := range c.Closers {
    81  		if err := single.Close(); err != nil {
    82  			log.Printf("[ERR] rpc/context: close error: %s", err)
    83  		}
    84  	}
    85  
    86  	return nil
    87  }