func NewServiceConnection(uuid string) (sc *ServiceConnection) { sc = new(ServiceConnection) sc.uuid = uuid sc.connections = map[string]*eventual2go.StreamController{} sc.connected = eventual2go.NewCompleter() sc.disconnected = eventual2go.NewCompleter() sc.handshake = eventual2go.NewCompleter() return }
// Demonstrates the basic usage of futures func ExampleFuture() { // create the completers, one we will complete with error, the other normall. completerNor := eventual2go.NewCompleter() completerErr := eventual2go.NewCompleter() // set up success handler var onsuccess eventual2go.CompletionHandler = func(d eventual2go.Data) eventual2go.Data { fmt.Println("SUCESS:", d) return "Hello Future Chaining" } // set up error handler var onerror eventual2go.ErrorHandler = func(e error) (eventual2go.Data, error) { fmt.Println("ERROR:", e) return nil, nil } // our long running async func mylongrunning := func(do_err bool, c *eventual2go.Completer) { time.Sleep(1 * time.Second) if do_err { c.CompleteError(errors.New("Hello Future Error")) } else { c.Complete("Hello Future") } } // get the futures fNor := completerNor.Future() fErr := completerErr.Future() // register the handlers // we chain the succes fNor.Then(onsuccess).Then(onsuccess) fNor.Err(onerror) fErr.Then(onsuccess) fErr.Err(onerror) // execute the functions go mylongrunning(false, completerNor) go mylongrunning(true, completerErr) // wait for futures to complete fNor.WaitUntilComplete() fErr.WaitUntilComplete() // everything is async, so the future is maybe complete, but the handlers must not have been executed necessarily, so we wait 10 ms time.Sleep(10 * time.Millisecond) }
func NewIncoming(addr string) (i *Incoming, err error) { i = &Incoming{ addr: addr, in: NewMessageStreamController(), close: eventual2go.NewCompleter(), closed: eventual2go.NewCompleter(), } err = i.setupSocket() if err == nil { go i.listen() } return }
func New(conf *Config) (b *Beacon, err error) { b = &Beacon{ m: &sync.Mutex{}, conf: conf, signals: NewSignalStreamController(), silence: eventual2go.NewCompleter(), stop: eventual2go.NewCompleter(), } b.init() err = b.setup() return }
func NewOutgoing(uuid config.UUID, targetAddress string, targetPort int) (out *Outgoing, err error) { skt, err := zmq4.NewSocket(zmq4.DEALER) if err != nil { return } err = skt.SetIdentity(string(uuid)) if err != nil { return } err = skt.Connect(fmt.Sprintf("tcp://%s:%d", targetAddress, targetPort)) if err != nil { return } out = &Outgoing{ m: &sync.Mutex{}, skt: skt, closed: eventual2go.NewCompleter(), } return }
func NewClient(uuid, localAddr string, daemonAddr string, daemonPortUdp int, servicetype string, ad *appdescriptor.AppDescriptor, addresses []string) (c *Client) { c = new(Client) c.logger = log.New(os.Stdout, "client ", log.Lshortfile) c.logger.Println("starting") c.uuid = uuid c.ad = ad c.addresses = addresses c.servicetype = servicetype c.localAddr = localAddr c.daemonAddr = daemonAddr c.daemonPortUdp = daemonPortUdp c.stop = eventual2go.NewCompleter() incoming, err := connection.NewIncoming(localAddr) if err != nil { panic(err) } c.localPort = incoming.Port() c.logger.Println("incoming port is", c.localPort) c.stop.Future().Then(stopIncoming(incoming)) msg_in := incoming.In().Where(ValidMessage) c.arrived = msg_in.Where(IsMessage(SERVICE_ARRIVE)).Transform(ToServiceArrivedMessage) c.gone = msg_in.Where(IsMessage(SERVICE_GONE)).Transform(ToServiceGone) msg_in.Where(IsMessage(HELLO)).Listen(c.onHello) return }
func NewAnnouncer(uuid string, addresses []string, servicetype string, desc *appdescriptor.AppDescriptor) (a *Announcer) { cfg := config.DefaultLocalhost() a = new(Announcer) a.announced = eventual2go.NewCompleter() a.logger = log.New(cfg.Logger(), fmt.Sprintf("announcer %s ", uuid), log.Lshortfile) a.new = eventual2go.NewStreamController() a.servicetype = servicetype addrs := []string{} a.clientPorts = map[string]int{} for _, addr := range addresses { as := strings.Split(addr, ":") addrs = append(addrs, as[0]) p, _ := strconv.ParseInt(as[1], 0, 0) a.clientPorts[as[0]] = int(p) a.logger.Println("adding address", as[0], int(p)) } cfg.NetworkInterfaces = addrs a.node = node.New(uuid, cfg, desc.AsTagSet()) a.r = eventual2go.NewReactor() a.r.React("first_join", a.announce) a.r.AddFuture("first_join", a.node.Join().First()) a.r.React("service_found", a.replyToServiceQuery) a.r.AddStream("service_found", a.node.Queries().WhereNot(isService(a.servicetype))) a.logger.Println("setup finished") return }
func NewClient(uuid, localAddr string, daemonAddr string, daemonPortUdp int, servicetype string, ad string, addresses []string, ports []int) (c *Client) { incoming, err := connection.NewIncoming(localAddr) if err != nil { panic(err) } c = &Client{ uuid: uuid, localAddr: localAddr, daemonAddr: daemonAddr, daemonPortUdp: daemonPortUdp, servicetype: servicetype, ad: ad, addresses: addresses, ports: ports, localPort: incoming.Port(), logger: log.New(os.Stdout, "client ", log.Lshortfile), stop: eventual2go.NewCompleter(), } c.logger.Println("starting") c.logger.Println("incoming port is", c.localPort) c.stop.Future().Then(stopIncoming(incoming)) msg_in := incoming.In().Where(ValidMessage) c.arrived = msg_in.Where(IsMessage(SERVICE_ARRIVE)).Transform(ToServiceArrivedMessage) c.gone = msg_in.Where(IsMessage(SERVICE_GONE)).Transform(ToServiceGone) msg_in.Where(IsMessage(HELLO)).Listen(c.onHello) return }
func (b *Beacon) init() { b.in = eventual2go.NewStreamController() b.stop = make(chan struct{}) b.outConns = []*net.UDPConn{} b.silence = eventual2go.NewCompleter() b.silent = true b.logger = log.New(b.conf.Logger, fmt.Sprintf("beacon %v ", b.payload[1]), log.Lshortfile) }
func (b *Beacon) Ping() { b.m.Lock() defer b.m.Unlock() if b.silence.Completed() { b.silence = eventual2go.NewCompleter() } go b.ping() }
func (b *Beacon) Silence() { b.m.Lock() defer b.m.Unlock() if !b.silent { b.silence.Complete(nil) b.silence = eventual2go.NewCompleter() b.silent = true } }
func NewService(dsc *servicedescriptor.ServiceDescriptor, servicetype string, cfg *config.Config, codecs []byte) (s *Service) { s = new(Service) if cfg.UUID == "" { id, _ := uid.NewV4() cfg.UUID = id.String() } s.uuid = cfg.UUID s.logger = log.New(cfg.Logger(), fmt.Sprintf("service %s ", s.uuid), log.Lshortfile) s.serviceDescriptor = dsc s.logger.Println("ServiceDesctiptor TagsSet is", dsc.AsTagSet()) s.servicetype = servicetype s.codecs = codecs s.newpeers = eventual2go.NewStreamController() s.gonepeers = eventual2go.NewStreamController() s.incoming = map[string]*connection.Incoming{} s.in = eventual2go.NewStreamController() s.connectedServices = map[string]*ServiceConnection{} s.connected = eventual2go.NewCompleter() s.disconnected = eventual2go.NewCompleter() s.remove = eventual2go.NewCompleter() s.r = eventual2go.NewReactor() s.r.React("service_arrived", s.serviceArrived) s.r.React("service_gone", s.serviceGone) s.r.React("announce_finish", s.announced) s.r.React("service_shake_hand", s.serviceHandshake) s.r.AddStream("service_shake_hand", s.in.Where(messages.Is(messages.HELLO))) s.r.React("service_shake_hand_reply", s.serviceHandShakeReply) s.r.AddStream("service_shake_hand_reply", s.in.Where(messages.Is(messages.HELLO_OK))) s.createIncoming(cfg) s.createAnnouncer(cfg) return }
func New(cfg *config.Config) (m *Manager, err error) { m = &Manager{ r: eventual2go.NewReactor(), connected: typed_events.NewBoolStreamController(), peers: map[config.UUID]*peer.Peer{}, arrive: config.NewUUIDStreamController(), leave: config.NewUUIDStreamController(), guaranteedMessages: map[messages.Message]*peer.Peer{}, messageIn: connection.NewMessageStreamController(), logger: log.New(cfg.Logger(), fmt.Sprintf("%s MANAGER ", cfg.UUID()), 0), shutdown: eventual2go.NewShutdown(), shutdownComplete: eventual2go.NewCompleter(), } m.r.React(peerLeave{}, m.peerLeave) m.r.React(peerConnected{}, m.peerConnected) m.r.OnShutdown(m.onShutdown) for _, iface := range cfg.Interfaces() { var i *connection.Incoming i, err = connection.NewIncoming(iface) if err != nil { m.logger.Println("ERROR setting up incoming:", err) m.Shutdown() return } m.shutdown.Register(i) m.messageIn.Join(i.In().Where(filterMessages)) var t *tracker.Tracker t, err = tracker.New(iface, i.Port(), cfg) if err != nil { m.logger.Println("ERROR setting up tracker:", err) m.Shutdown() return } m.tracker = append(m.tracker, t) m.shutdown.Register(t) m.r.AddStream(peerLeave{}, t.Leave().Stream) var d *discoverer.Discoverer d = discoverer.New(t.Join(), i, cfg) m.r.AddStream(peerConnected{}, d.ConnectedPeers().Stream) } return }
func (m *Manager) SendGuaranteed(msg messages.Message) (c *eventual2go.Completer) { m.r.Lock() defer m.r.Unlock() if len(m.peers) == 0 { m.logger.Println("no peer found for guaranteed message, storing") m.guaranteedMessages[msg] = nil } else { for _, p := range m.peers { m.logger.Println("Sending guaranteed message to", p.UUID()) m.guaranteedMessages[msg] = p p.Send(msg) } } c = eventual2go.NewCompleter() c.Future().Then(m.acknowdledeReception(msg)) return }
func NewAnnouncer(uuid string, servicetype string, desc *servicedescriptor.ServiceDescriptor, cfg *config.Config, ports []int) (a *Announcer) { a = &Announcer{ announced: eventual2go.NewCompleter(), clientPorts: map[string]int{}, logger: log.New(cfg.Logger(), fmt.Sprintf("announcer %s ", uuid), log.Lshortfile), new: eventual2go.NewStreamController(), node: node.New(uuid, cfg, desc.AsTagSet()), servicetype: servicetype, } a.setPorts(cfg, ports) a.initReactor() return }
func NewPeerCompleter() *PeerCompleter { return &PeerCompleter{eventual2go.NewCompleter()} }
func NewStringSliceCompleter() *StringSliceCompleter { return &StringSliceCompleter{eventual2go.NewCompleter()} }
func NewResultCompleter() *ResultCompleter { return &ResultCompleter{eventual2go.NewCompleter()} }
func NewNodeCompleter() *NodeCompleter { return &NodeCompleter{eventual2go.NewCompleter()} }
func NewIntCompleter() *IntCompleter { return &IntCompleter{eventual2go.NewCompleter()} }
func NewMessageCompleter() *MessageCompleter { return &MessageCompleter{eventual2go.NewCompleter()} }
func NewSignalCompleter() *SignalCompleter { return &SignalCompleter{eventual2go.NewCompleter()} }
func NewBoolCompleter() *BoolCompleter { return &BoolCompleter{eventual2go.NewCompleter()} }
func NewUUIDCompleter() *UUIDCompleter { return &UUIDCompleter{eventual2go.NewCompleter()} }