func (d *delegate) Initialize(ctx application.Context) { req, ptr := discovery.CreateMessagePipeForDiscovery() ctx.ConnectToApplication("https://mojo.v.io/discovery.mojo").ConnectToService(&req) ad := discovery.Advertisement{ InterfaceName: "v.io/discovery.T", Addresses: []string{"localhost:1000"}, Attributes: &map[string]string{"foo": "abc"}, Attachments: &map[string][]byte{"bar": []byte{1, 2, 3}}, } dProxy := discovery.NewDiscoveryProxy(ptr, bindings.GetAsyncWaiter()) id, closerPtr, e1, e2 := dProxy.Advertise(ad, nil) if e1 != nil || e2 != nil { log.Printf("Failed to advertise: %v, %v", e1, e2) return } log.Printf("Advertising %x...", *id) d.stop = func() { cProxy := discovery.NewCloserProxy(*closerPtr, bindings.GetAsyncWaiter()) cProxy.Close() cProxy.Close_Proxy() dProxy.Close_Proxy() } }
func scan(d mojom.Discovery, query string) (<-chan mojom.Update_Pointer, func(), error) { ch := make(chan mojom.Update_Pointer, 10) handler := &mockScanHandler{ch} req, ptr := mojom.CreateMessagePipeForScanHandler() stub := mojom.NewScanHandlerStub(req, handler, bindings.GetAsyncWaiter()) closer, e1, e2 := d.Scan(query, ptr) if e1 != nil { close(ch) return nil, nil, errors.New(e1.Msg) } if e2 != nil { close(ch) return nil, nil, e2 } wg := new(sync.WaitGroup) wg.Add(1) go func() { defer wg.Done() for { if err := stub.ServeRequest(); err != nil { connErr, ok := err.(*bindings.ConnectionError) if !ok || !connErr.Closed() { log.Println(err) } break } } }() stop := func() { p := mojom.NewCloserProxy(*closer, bindings.GetAsyncWaiter()) p.Close() p.Close_Proxy() stub.Close() wg.Wait() close(ch) } return ch, stop, nil }
func (d *delegate) Initialize(ctx application.Context) { req, ptr := discovery.CreateMessagePipeForDiscovery() ctx.ConnectToApplication("https://mojo.v.io/discovery.mojo").ConnectToService(&req) scanHandlerReq, scanHandlerPtr := discovery.CreateMessagePipeForScanHandler() scanHandlerStub := discovery.NewScanHandlerStub(scanHandlerReq, &scanHandler{}, bindings.GetAsyncWaiter()) dProxy := discovery.NewDiscoveryProxy(ptr, bindings.GetAsyncWaiter()) closerPtr, e1, e2 := dProxy.Scan(`v.InterfaceName="v.io/discovery.T"`, scanHandlerPtr) if e1 != nil || e2 != nil { log.Printf("Failed to scan: %v, %v", e1, e2) scanHandlerStub.Close() dProxy.Close_Proxy() return } go func() { for { if err := scanHandlerStub.ServeRequest(); err != nil { connErr, ok := err.(*bindings.ConnectionError) if !ok || !connErr.Closed() { log.Println(err) } break } } }() d.stop = func() { cProxy := discovery.NewCloserProxy(*closerPtr, bindings.GetAsyncWaiter()) cProxy.Close() cProxy.Close_Proxy() scanHandlerStub.Close() dProxy.Close_Proxy() } }
func AppTestGlobalDiscoveryBasic(t *testing.T, mctx application.Context) { ads := []mojom.Advertisement{ { Id: &[internal.AdIdLen]uint8{1, 2, 3}, Addresses: []string{"/h1:123/x"}, InterfaceName: "foo/bar/baz", }, { Addresses: []string{"/h1:123/y"}, InterfaceName: "foo/bar/baz", }, } d1 := newGlobalDiscovery(mctx, 0) defer d1.Close_Proxy() var stops []func() for i, ad := range ads { id, closer, e1, e2 := d1.Advertise(ad, nil) if e1 != nil || e2 != nil { t.Fatalf("ad[%d]: failed to advertise: %v, %v", i, e1, e2) } if id == nil { t.Errorf("ad[%d]: got nil id", i) continue } if ad.Id == nil { ads[i].Id = id } else if *id != *ad.Id { t.Errorf("ad[%d]: got ad id %v, but wanted %v", i, *id, *ad.Id) } stop := func() { p := mojom.NewCloserProxy(*closer, bindings.GetAsyncWaiter()) p.Close() p.Close_Proxy() } stops = append(stops, stop) } // Make sure none of advertisements are discoverable by the same discovery instance. if err := scanAndMatch(d1, ``); err != nil { t.Error(err) } // Create a new discovery instance. All advertisements should be discovered with that. d2 := newGlobalDiscovery(mctx, 1*time.Millisecond) defer d2.Close_Proxy() if err := scanAndMatch(d2, `k="01020300000000000000000000000000"`, ads[0]); err != nil { t.Error(err) } if err := scanAndMatch(d2, ``, ads...); err != nil { t.Error(err) } // Open a new scan channel and consume expected advertisements first. scanCh, scanStop, err := scan(d2, `k="01020300000000000000000000000000"`) if err != nil { t.Fatal(err) } defer scanStop() update := <-scanCh if err := matchFound([]mojom.Update_Pointer{update}, ads[0]); err != nil { t.Error(err) } // Make sure scan returns the lost advertisement when advertising is stopped. stops[0]() update = <-scanCh if err := matchLost([]mojom.Update_Pointer{update}, ads[0]); err != nil { t.Error(err) } // Also it shouldn't affect the other. if err := scanAndMatch(d2, fmt.Sprintf(`k="%s"`, hex.EncodeToString(ads[1].Id[:])), ads[1]); err != nil { t.Error(err) } // Stop advertising the remaining one; Shouldn't discover any advertisements. stops[1]() if err := scanAndMatch(d2, ``); err != nil { t.Error(err) } }