예제 #1
0
파일: clonesrv2.go 프로젝트: JeremyOT/zmq4
func main() {
	//  Prepare our context and sockets
	publisher, _ := zmq.NewSocket(zmq.PUB)
	publisher.Bind("tcp://*:5557")

	sequence := int64(0)
	rand.Seed(time.Now().UnixNano())

	//  Start state manager and wait for synchronization signal
	updates, _ := zmq.NewSocket(zmq.PAIR)
	updates.Bind("inproc://pipe")
	go state_manager()
	updates.RecvMessage(0) // "READY"

	for {
		//  Distribute as key-value message
		sequence++
		kvmsg := kvsimple.NewKvmsg(sequence)
		kvmsg.SetKey(fmt.Sprint(rand.Intn(10000)))
		kvmsg.SetBody(fmt.Sprint(rand.Intn(1000000)))
		if kvmsg.Send(publisher) != nil {
			break
		}
		if kvmsg.Send(updates) != nil {
			break
		}
	}
	fmt.Printf("Interrupted\n%d messages out\n", sequence)
}
예제 #2
0
파일: clonesrv1.go 프로젝트: JeremyOT/zmq4
func main() {
	//  Prepare our context and publisher socket
	publisher, _ := zmq.NewSocket(zmq.PUB)
	publisher.Bind("tcp://*:5556")
	time.Sleep(200 * time.Millisecond)

	kvmap := make(map[string]*kvsimple.Kvmsg)
	rand.Seed(time.Now().UnixNano())

	sequence := int64(1)
	for ; true; sequence++ {
		//  Distribute as key-value message
		kvmsg := kvsimple.NewKvmsg(sequence)
		kvmsg.SetKey(fmt.Sprint(rand.Intn(10000)))
		kvmsg.SetBody(fmt.Sprint(rand.Intn(1000000)))
		err := kvmsg.Send(publisher)
		kvmsg.Store(kvmap)
		if err != nil {
			break
		}
	}
	fmt.Printf("Interrupted\n%d messages out\n", sequence)
}
예제 #3
0
파일: clonesrv3.go 프로젝트: JeremyOT/zmq4
func main() {
	snapshot, _ := zmq.NewSocket(zmq.ROUTER)
	snapshot.Bind("tcp://*:5556")
	publisher, _ := zmq.NewSocket(zmq.PUB)
	publisher.Bind("tcp://*:5557")
	collector, _ := zmq.NewSocket(zmq.PULL)
	collector.Bind("tcp://*:5558")

	//  The body of the main task collects updates from clients and
	//  publishes them back out to clients:

	sequence := int64(0)
	kvmap := make(map[string]*kvsimple.Kvmsg)

	poller := zmq.NewPoller()
	poller.Add(collector, zmq.POLLIN)
	poller.Add(snapshot, zmq.POLLIN)
LOOP:
	for {
		polled, err := poller.Poll(1000 * time.Millisecond)
		if err != nil {
			break
		}
		for _, item := range polled {
			switch socket := item.Socket; socket {
			case collector:
				//  Apply state update sent from client
				kvmsg, err := kvsimple.RecvKvmsg(collector)
				if err != nil {
					break LOOP //  Interrupted
				}
				sequence++
				kvmsg.SetSequence(sequence)
				kvmsg.Send(publisher)
				kvmsg.Store(kvmap)
				fmt.Println("I: publishing update", sequence)
			case snapshot:
				//  Execute state snapshot request
				msg, err := snapshot.RecvMessage(0)
				if err != nil {
					break LOOP
				}
				identity := msg[0]

				//  Request is in second frame of message
				request := msg[1]
				if request != "ICANHAZ?" {
					fmt.Println("E: bad request, aborting")
					break LOOP
				}
				//  Send state snapshot to client

				//  For each entry in kvmap, send kvmsg to client
				for _, kvmsg := range kvmap {
					snapshot.Send(identity, zmq.SNDMORE)
					kvmsg.Send(snapshot)
				}

				//  Now send END message with sequence number
				fmt.Println("I: sending shapshot =", sequence)
				snapshot.Send(identity, zmq.SNDMORE)
				kvmsg := kvsimple.NewKvmsg(sequence)
				kvmsg.SetKey("KTHXBAI")
				kvmsg.SetBody("")
				kvmsg.Send(snapshot)
			}
		}
	}
	fmt.Printf("Interrupted\n%d messages handled\n", sequence)
}
예제 #4
0
파일: clonecli4.go 프로젝트: JeremyOT/zmq4
func main() {
	snapshot, _ := zmq.NewSocket(zmq.DEALER)
	snapshot.Connect("tcp://localhost:5556")
	subscriber, _ := zmq.NewSocket(zmq.SUB)
	subscriber.SetSubscribe(SUBTREE)
	subscriber.Connect("tcp://localhost:5557")
	publisher, _ := zmq.NewSocket(zmq.PUSH)
	publisher.Connect("tcp://localhost:5558")

	kvmap := make(map[string]*kvsimple.Kvmsg)
	rand.Seed(time.Now().UnixNano())

	//  We first request a state snapshot:
	sequence := int64(0)
	snapshot.SendMessage("ICANHAZ?", SUBTREE)
	for {
		kvmsg, err := kvsimple.RecvKvmsg(snapshot)
		if err != nil {
			break //  Interrupted
		}
		if key, _ := kvmsg.GetKey(); key == "KTHXBAI" {
			sequence, _ := kvmsg.GetSequence()
			fmt.Println("I: received snapshot =", sequence)
			break //  Done
		}
		kvmsg.Store(kvmap)
	}
	snapshot.Close()

	poller := zmq.NewPoller()
	poller.Add(subscriber, zmq.POLLIN)
	alarm := time.Now().Add(1000 * time.Millisecond)
	for {
		tickless := alarm.Sub(time.Now())
		if tickless < 0 {
			tickless = 0
		}
		polled, err := poller.Poll(tickless)
		if err != nil {
			break //  Context has been shut down
		}
		if len(polled) == 1 {
			kvmsg, err := kvsimple.RecvKvmsg(subscriber)
			if err != nil {
				break //  Interrupted
			}

			//  Discard out-of-sequence kvmsgs, incl. heartbeats
			if seq, _ := kvmsg.GetSequence(); seq > sequence {
				sequence = seq
				kvmsg.Store(kvmap)
				fmt.Println("I: received update =", sequence)
			}
		}
		//  If we timed-out, generate a random kvmsg
		if time.Now().After(alarm) {
			kvmsg := kvsimple.NewKvmsg(0)
			kvmsg.SetKey(fmt.Sprintf("%s%d", SUBTREE, rand.Intn(10000)))
			kvmsg.SetBody(fmt.Sprint(rand.Intn(1000000)))
			kvmsg.Send(publisher)
			alarm = time.Now().Add(1000 * time.Millisecond)
		}
	}
	fmt.Printf("Interrupted\n%d messages in\n", sequence)
}
예제 #5
0
파일: clonesrv2.go 프로젝트: JeremyOT/zmq4
func state_manager() {
	kvmap := make(map[string]*kvsimple.Kvmsg)

	pipe, _ := zmq.NewSocket(zmq.PAIR)
	pipe.Connect("inproc://pipe")
	pipe.SendMessage("READY")
	snapshot, _ := zmq.NewSocket(zmq.ROUTER)
	snapshot.Bind("tcp://*:5556")

	poller := zmq.NewPoller()
	poller.Add(pipe, zmq.POLLIN)
	poller.Add(snapshot, zmq.POLLIN)
	sequence := int64(0) //  Current snapshot version number
LOOP:
	for {
		polled, err := poller.Poll(-1)
		if err != nil {
			break //  Context has been shut down
		}
		for _, item := range polled {
			switch socket := item.Socket; socket {
			case pipe:
				//  Apply state update from main thread
				kvmsg, err := kvsimple.RecvKvmsg(pipe)
				if err != nil {
					break LOOP //  Interrupted
				}
				sequence, _ = kvmsg.GetSequence()
				kvmsg.Store(kvmap)
			case snapshot:
				//  Execute state snapshot request
				msg, err := snapshot.RecvMessage(0)
				if err != nil {
					break LOOP //  Interrupted
				}
				identity := msg[0]
				//  Request is in second frame of message
				request := msg[1]
				if request != "ICANHAZ?" {
					fmt.Println("E: bad request, aborting")
					break LOOP
				}
				//  Send state snapshot to client

				//  For each entry in kvmap, send kvmsg to client
				for _, kvmsg := range kvmap {
					snapshot.Send(identity, zmq.SNDMORE)
					kvmsg.Send(snapshot)
				}

				// Give client some time to deal with it.
				// This reduces the risk that the client won't see
				// the END message, but it doesn't eliminate the risk.
				time.Sleep(100 * time.Millisecond)

				//  Now send END message with sequence number
				fmt.Printf("Sending state shapshot=%d\n", sequence)
				snapshot.Send(identity, zmq.SNDMORE)
				kvmsg := kvsimple.NewKvmsg(sequence)
				kvmsg.SetKey("KTHXBAI")
				kvmsg.SetBody("")
				kvmsg.Send(snapshot)
			}
		}
	}
}