Пример #1
0
// NewServer creates a qrpc server which has not started to accept requests yet.
func NewServer(cfg *Config) *Server {
	log.Printf("-> NewServer(%v)\n", cfg)

	return &Server{
		cfg: cfg,
		rpc: grpc.NewServer(grpc.MaxConcurrentStreams(math.MaxUint32)),
		cluster: &cluster{
			key:     fmt.Sprintf("peer-%s", keySuffix()),
			timeout: cfg.ClusterRequestTimeout,
			peers:   make(map[string]*internal.Peer),
		},
		cancelWatcher: nil,

		mtx: &sync.Mutex{},
		data: diskv.New(diskv.Options{
			BasePath:     cfg.DataBasePath,
			Transform:    transformKey,
			CacheSizeMax: cfg.MaxCacheSize,
		}),
	}
}
Пример #2
0
func StartBlockServer(name string) *BlockServer {
	bs := new(BlockServer)

	// Node id for kademlia
	var id NodeID

	content, err := ioutil.ReadFile(name + ".id")
	if err == nil {
		id = MakeNode(content)
		//Do something
	} else {
		b := MakeGUID()
		id = MakeNode(b)
		ioutil.WriteFile(name+".id", b, 0644)
	}

	addr := strings.Split(name, ":")[0]
	port, _ := strconv.Atoi(strings.Split(name, ":")[1])

	bs.contact = Contact{id, addr, port}
	flatTransform := func(s string) []string { return []string{} }
	bs.fileData = diskv.New(diskv.Options{
		BasePath:  name + ".dat",
		Transform: flatTransform,
		// 100 Mb cache max
		CacheSizeMax: 104857600,
	})

	bs.data = make(map[Key]string)
	bs.server = web.NewServer()
	logFile, err := os.OpenFile(name+".log", os.O_CREATE|os.O_APPEND, 0644)
	if err == nil {
		bs.server.SetLogger(log.New(logFile, "", log.Ldate|log.Ltime))
		fmt.Printf("Set logger to %v\n", logFile)
		defer logFile.Close()
	}
	bs.routingTable = NewRoutingTable(5, MakeByteSlice(id))

	go func() {
		// Primitive store, stores the key,value in the local data
		bs.server.Post("/store", func(c *web.Context) string {
			bs.updateContactFromHeader(c)
			bs.prepareResponse(c)
			return bs.Store(c)
		})

		// Kademlia based store, does smart stuff
		bs.server.Post("/distributed/store", func(c *web.Context) string {
			bs.updateContactFromHeader(c)
			bs.prepareResponse(c)
			return bs.IterativeStore(c)
		})

		// Primitive find-value
		bs.server.Get("/find-value/(.*)", func(c *web.Context, key string) string {
			c.ContentType("json")
			bs.updateContactFromHeader(c)
			bs.prepareResponse(c)
			return bs.FindValue(c, key)
		})

		// Kademlia based find-value, does smart stuff
		bs.server.Get("/distributed/find-value/(.*)", func(c *web.Context, key string) string {
			c.ContentType("json")
			bs.updateContactFromHeader(c)
			bs.prepareResponse(c)
			return bs.IterativeFindValue(c, key)
		})

		// Primitive find-node
		bs.server.Get("/find-node/(.*)", func(c *web.Context, node string) string {
			c.ContentType("json")
			bs.updateContactFromHeader(c)
			bs.prepareResponse(c)
			return bs.FindNode(c, node)
		})

		// Kademlia based find-node, does smart stuff
		bs.server.Get("/distributed/find-node/(.*)", func(c *web.Context, node string) string {
			c.ContentType("json")
			bs.updateContactFromHeader(c)
			bs.prepareResponse(c)
			return bs.IterativeFindNode(c, node)
		})

		// Ping endpoint, sees if the server is alive
		bs.server.Get("/ping", func(c *web.Context) string {
			bs.updateContactFromHeader(c)
			bs.prepareResponse(c)
			return RespondOk()
		})

		// Following are for the replication server to do smart things
		bs.server.Get("/keys", func(c *web.Context) string {
			c.ContentType("json")
			keys := make([]string, 0)
			for key := range bs.fileData.Keys() {
				keys = append(keys, key)
			}
			return RespondWithData(keys)
		})

		// Re-replicates a key that this node has
		bs.server.Post("/replicate", func(c *web.Context) string {
			bs.prepareResponse(c)
			key := c.Params["key"]
			value, ok := bs.fileData.Read(key)
			if ok == nil {
				c.Params["data"] = string(value)
				return bs.IterativeStore(c)
			}
			return RespondNotFound()
		})

		bs.server.Get("/contacts", func(c *web.Context) string {
			bs.prepareResponse(c)
			c.ResponseWriter.Header().Add("Access-Control-Allow-Origin", "*")
			return RespondWithData(bs.routingTable.AllContacts())
		})

		fmt.Printf("Listening on %v\n", name)
		bs.server.Run(name)
	}()

	return bs
}