first
This commit is contained in:
143
main.go
Normal file
143
main.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/rpc"
|
||||
"time"
|
||||
)
|
||||
|
||||
type GrainServer struct {
|
||||
Host string
|
||||
}
|
||||
|
||||
type Grain interface {
|
||||
HandleMessage(message *Message, reply *CartGrain) error
|
||||
}
|
||||
|
||||
func NewServer(hostname string) *GrainServer {
|
||||
return &GrainServer{
|
||||
Host: hostname,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *GrainServer) Start(port int, instance Grain) (net.Listener, error) {
|
||||
rpc.Register(instance)
|
||||
rpc.HandleHTTP()
|
||||
return net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
}
|
||||
|
||||
type CartGrain struct {
|
||||
Skus []string
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
Type string
|
||||
Content string
|
||||
}
|
||||
|
||||
type Registry interface {
|
||||
Register(address string, id string) error
|
||||
Get(id string) (*string, error)
|
||||
}
|
||||
|
||||
type MemoryRegistry struct {
|
||||
registry map[string]string
|
||||
}
|
||||
|
||||
func (r *MemoryRegistry) Register(address string, id string) error {
|
||||
r.registry[id] = address
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *MemoryRegistry) Get(id string) (*string, error) {
|
||||
addr, ok := r.registry[id]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("id not found")
|
||||
}
|
||||
return &addr, nil
|
||||
}
|
||||
|
||||
func (c *CartGrain) HandleMessage(message *Message, reply *CartGrain) error {
|
||||
fmt.Println("CartGrain received message: ", message)
|
||||
c.Skus = append(c.Skus, message.Content)
|
||||
*reply = *c
|
||||
return nil
|
||||
}
|
||||
|
||||
type ServerPool interface {
|
||||
GetOrSpawn(id string, ttl time.Time) (*string, error)
|
||||
}
|
||||
|
||||
type WebServer struct {
|
||||
ServerPool ServerPool
|
||||
}
|
||||
|
||||
type MemoryServerPool struct {
|
||||
port int
|
||||
local *GrainServer
|
||||
pool map[string]*string
|
||||
}
|
||||
|
||||
func (p *MemoryServerPool) GetOrSpawn(id string, ttl time.Duration) (*string, error) {
|
||||
addr, ok := p.pool[id]
|
||||
if !ok {
|
||||
prt := p.port
|
||||
p.port++
|
||||
s := NewServer("localhost")
|
||||
_, e := s.Start(prt, &CartGrain{})
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
//go http.Serve(l, nil)
|
||||
a := fmt.Sprintf("localhost:%d", prt)
|
||||
p.pool[id] = &a
|
||||
addr = &a
|
||||
}
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Create a new instance of the server
|
||||
pool := &MemoryServerPool{
|
||||
port: 1337,
|
||||
pool: make(map[string]*string),
|
||||
local: NewServer("localhost"),
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("GET /{id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
addr, err := pool.GetOrSpawn(id, time.Hour*1)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(*addr))
|
||||
})
|
||||
mux.HandleFunc("GET /add/{id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
addr, err := pool.GetOrSpawn(id, time.Hour*1)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
var cart CartGrain
|
||||
client, err := rpc.DialHTTP("tcp", *addr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
err = client.Call("CartGrain.HandleMessage", &Message{Type: "add", Content: "123"}, &cart)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Write([]byte(fmt.Sprintf("Cart: %v", cart.Skus)))
|
||||
})
|
||||
http.ListenAndServe(":8080", mux)
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user