Ejemplo n.º 1
0
// StartServer starts up a listened at 127.0.0.1:<port> with a key space distributed over a given number of buckets.
func StartServer(port uint, buckets uint) {

	if buckets == 0 {
		log.Fatalf("<buckets> be positive. got %d.\n", buckets)
	}

	var db metastore.MetaStore
	db.Init(buckets)
	log.Printf("created storage with %d buckets\n", buckets)

	// listening on localhost
	addr := "127.0.0.1:" + strconv.FormatUint(uint64(port), 10)
	listener, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatal(err)
	}
	defer listener.Close()
	log.Printf("server listening on port %d\n", port)

	for {
		c, err := listener.Accept()
		if err != nil {
			log.Fatal(err)
		}
		go handleConnection(c, &db)
	}
}
Ejemplo n.º 2
0
func handleConnection(c net.Conn, dbase *metastore.MetaStore) {
	defer closeConnection(c)

	fromAddr := c.RemoteAddr()
	log.Printf("[%s] new connection\n", fromAddr)

	buf := make([]byte, 1024)

	bucketIndex := dbase.GetHasher()

NEXTMESSAGE:

	_, err := c.Read(buf)
	if err != nil {
		return
	}

	msg, err := Parse(buf)
	if err != nil {
		return
	}

	i := bucketIndex(msg.key)

	switch msg.cmd {

	case GET:

		if value, ok := (*dbase).Bucket[i].Get(string(msg.key)); ok {
			b := []byte(value)
			b = append(b, EOM)
			_, err = c.Write(b)
		} else {
			_, err = c.Write([]byte{EOM})
		}
		if err != nil {
			return
		}
		goto NEXTMESSAGE

	case SET:

		(*dbase).Bucket[i].Set(string(msg.key), string(msg.arg))
		_, err = c.Write([]byte{SUCCESS})
		if err != nil {
			return
		}
		goto NEXTMESSAGE

	case DEL:

		(*dbase).Bucket[i].Delete(string(msg.key))
		_, err = c.Write([]byte{SUCCESS})
		if err != nil {
			return
		}
		goto NEXTMESSAGE

	case PUB:

		(*dbase).Bucket[i].Publish(string(msg.key), string(msg.arg))
		_, err = c.Write([]byte{SUCCESS})
		if err != nil {
			return
		}
		goto NEXTMESSAGE

	case SUB:

		outgoing := make(chan string)
		(*dbase).Bucket[i].Subscribe(string(msg.key), outgoing)
		for value := range outgoing {
			b := []byte(value)
			b = append(b, EOM)
			_, err := c.Write(b)
			if err != nil {
				close(outgoing)
				return
			}
		}

	default:
		return
	}
}