// 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, }), } }
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 }