예제 #1
0
파일: spqueue.cs 프로젝트: hnkien/zguide2
        static void Main(string[] args)
        {
            using (var context = new Context(1))
            {
                using (Socket frontend = context.Socket(SocketType.ROUTER), backend = context.Socket(SocketType.ROUTER))
                {
                    frontend.Bind("tcp://*:5555"); // For Clients
                    backend.Bind("tcp://*:5556"); // For Workers

                    //  Logic of LRU loop
                    //  - Poll backend always, frontend only if 1+ worker ready
                    //  - If worker replies, queue worker as ready and forward reply
                    //    to client if necessary
                    //  - If client requests, pop next worker and send request to it

                    //  Queue of available workers
                    var workerQueue = new Queue<byte[]>();

                    //  Handle worker activity on backend
                    backend.PollInHandler += (socket, revents) =>
                                                 {
                                                     var zmsg = new ZMessage(socket);
                                                     //  Use worker address for LRU routing
                                                     workerQueue.Enqueue(zmsg.Unwrap());

                                                     //  Forward message to client if it's not a READY
                                                     if (!Encoding.Unicode.GetString(zmsg.Address).Equals(LRU_READY))
                                                     {
                                                         zmsg.Send(frontend);
                                                     }
                                                 };

                    frontend.PollInHandler += (socket, revents) =>
                                                  {
                                                      //  Now get next client request, route to next worker
                                                      //  Dequeue and drop the next worker address
                                                      var zmsg = new ZMessage(socket);
                                                      zmsg.Wrap(workerQueue.Dequeue(), new byte[0]);
                                                      zmsg.Send(backend);
                                                  };

                    while (true)
                    {
                        int rc = Context.Poller(workerQueue.Count > 0
                                                    ? new List<Socket>(new Socket[] {frontend, backend})
                                                    : new List<Socket>(new Socket[] {backend}));

                        if (rc == -1)
                        {
                            break;
                        }
                    }
                }
            }
        }
예제 #2
0
파일: spworker.cs 프로젝트: hnkien/zguide2
        static void Main(string[] args)
        {
            using (var context = new Context(1))
            {
                using (var worker = context.Socket(SocketType.REQ))
                {
                    var randomizer = new Random(DateTime.Now.Millisecond);
                    var identity = ZHelpers.SetID(worker, Encoding.Unicode);
                    worker.Connect("tcp://localhost:5556");

                    Console.WriteLine("I: {0} worker ready", identity);
                    worker.Send("READY");

                    var cycles = 0;
                    while (true)
                    {
                        var zmsg = new ZMessage(worker);

                        cycles += 1;
                        if (cycles > 3 && randomizer.Next(0, 5) == 0)
                        {
                            Console.WriteLine("I: {0} simulating a crash", identity);
                            break;
                        }
                        else if (cycles > 3 && randomizer.Next(0, 5) == 0)
                        {
                            Console.WriteLine("I: {0} simulating CPU overload", identity);
                            System.Threading.Thread.Sleep(3000);
                        }
                        Console.WriteLine("I: {0} normal reply", identity);
                        System.Threading.Thread.Sleep(1000);
                        zmsg.Send(worker);
                    }
                }
            }
        }
예제 #3
0
파일: lruqueue2.cs 프로젝트: hnkien/zguide2
        public static void Main(string[] args)
        {
            var workers = new List<Thread>();
            var clients = new List<Thread>();

            //  Prepare our context and sockets
            using (var ctx = new Context(1))
            {
                using (Socket frontend = ctx.Socket(SocketType.ROUTER), backend = ctx.Socket(SocketType.ROUTER))
                {
                    frontend.Bind("tcp://*:5555");
                    backend.Bind("tcp://*:5556");

                    int clientId;
                    for (clientId = 0; clientId < Program.clients; clientId++)
                    {
                        clients.Add(new Thread(ClientTask));
                        clients[clientId].Start();
                    }

                    for (int workerId = 0; workerId < Program.workers; workerId++)
                    {
                        workers.Add(new Thread(WorkerTask));
                        workers[workerId].Start();
                    }

                    //  Logic of LRU loop
                    //  - Poll backend always, frontend only if 1+ worker ready
                    //  - If worker replies, queue worker as ready and forward reply
                    //    to client if necessary
                    //  - If client requests, pop next worker and send request to it

                    //  Queue of available workers
                    var workerQueue = new Queue<byte[]>();

                    //  Handle worker activity on backend
                    backend.PollInHandler += (socket, revents) =>
                                                 {
                                                     var zmsg = new ZMessage(socket);
                                                     //  Use worker address for LRU routing
                                                     workerQueue.Enqueue(zmsg.Unwrap());

                                                     //  Forward message to client if it's not a READY
                                                     if (!Encoding.Unicode.GetString(zmsg.Address).Equals("READY"))
                                                     {
                                                         zmsg.Send(frontend);
                                                     }
                                                 };

                    frontend.PollInHandler += (socket, revents) =>
                                                  {
                                                      //  Now get next client request, route to next worker
                                                      //  Dequeue and drop the next worker address
                                                      var zmsg = new ZMessage(socket);
                                                      zmsg.Wrap(workerQueue.Dequeue(), new byte[0]);
                                                      zmsg.Send(backend);
                                                  };

                    while (true)
                    {
                        int rc = Context.Poller(workerQueue.Count > 0
                                           ? new List<Socket>(new Socket[] {frontend, backend})
                                           : new List<Socket>(new Socket[] {backend}));

                        if (rc == -1)
                        {
                            break;
                        }
                    }
                }
            }
        }
예제 #4
0
파일: lruqueue2.cs 프로젝트: hnkien/zguide2
        private static void WorkerTask()
        {
            using (var ctx = new Context(1))
            {
                using (var worker = ctx.Socket(SocketType.REQ))
                {
                    ZHelpers.SetID(worker, Encoding.Unicode);
                    worker.Connect("tcp://localhost:5556");

                    //  Tell broker we're ready for work
                    worker.Send("READY", Encoding.Unicode);

                    while (true)
                    {
                        var zmsg = new ZMessage(worker);
                        Console.WriteLine("Worker: {0}", Encoding.Unicode.GetString(zmsg.Body));
                        zmsg.StringToBody("OK");
                        zmsg.Send(worker);
                    }
                }
            }
        }
예제 #5
0
        static void Main(string[] args)
        {
            using (var context = new Context(1))
            {
                int interval = INTERVAL_INIT;
                int liveness = HEARTBEAT_LIVENESS;

                while (true)
                {
                    int cylces = 0;

                    using (Socket worker = ConnectWorker(context))
                    {
                        worker.PollInHandler += (socket, revents) =>
                        {
                            var zmsg = new ZMessage(socket);

                            byte[] identity = zmsg.Unwrap();

                            switch (Encoding.Unicode.GetString(zmsg.Address))
                            {
                                case PPP_HEARTBEAT:
                                    interval = INTERVAL_INIT;
                                    liveness = HEARTBEAT_LIVENESS;
                                    break;
                                default:
                                    if (zmsg.FrameCount > 1)
                                    {
                                        if (!doTheWork(cylces++))
                                        {
                                            break;
                                        }
                                        interval = INTERVAL_INIT;
                                        liveness = HEARTBEAT_LIVENESS;
                                        Console.WriteLine("W: work completed");
                                        zmsg.Send(worker);
                                    }
                                    else
                                    {
                                        Console.WriteLine("E: invalied message {0}", identity);
                                    }
                                    break;
                            };
                        };

                        //Send out heartbeats at regular intervals
                        DateTime heartbeat_at = DateTime.Now.AddMilliseconds(HEARTBEAT_INTERVAL);

                        while (true)
                        {
                            List<Socket> pollItems = new List<Socket>(new Socket[] { worker });
                            Context.Poller(pollItems, HEARTBEAT_INTERVAL * 1000);

                            //If liveness hits zero, queue is considered disconnected
                            if (--liveness <= 0)
                            {
                                Console.WriteLine("W: heartbeat failure, can't reach queue.");
                                Console.WriteLine("W: reconnecting in {0} msecs...", interval);

                                try
                                {
                                    Thread.Sleep(interval);
                                }
                                catch (System.Exception ex)
                                {
                                    Console.WriteLine(ex.Message);
                                }

                                //Exponential Backoff
                                if (interval < INTERVAL_MAX)
                                    interval *= 2;

                                liveness = HEARTBEAT_LIVENESS;

                                //Break the while loop and start the connection over
                                break;
                            }

                            //Send heartbeat to queue if it's time
                            if (DateTime.Now > heartbeat_at)
                            {
                                heartbeat_at = DateTime.Now.AddMilliseconds(HEARTBEAT_INTERVAL);
                                ZMessage zmsg = new ZMessage(PPP_HEARTBEAT);
                                zmsg.Send(worker);
                            }
                        }
                    }
                }
            }
        }
예제 #6
0
파일: peering2.cs 프로젝트: hnkien/zguide2
        public static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("Usage: peering2 <myself> <peer_1> … <peer_N>");
                return;
            }

            var myself = args[0];
            Console.WriteLine("Hello, I am " + myself);

            using (var context = new Context(1))
            {
                using (Socket cloudfe = context.Socket(SocketType.ROUTER), cloudbe = context.Socket(SocketType.ROUTER),
                    localfe = context.Socket(SocketType.ROUTER), localbe = context.Socket(SocketType.ROUTER))
                {
                    cloudFeAddress = "tcp://127.0.0.1:" + myself;
                    cloudfe.Identity = Encoding.Unicode.GetBytes(myself);
                    cloudfe.Bind(cloudFeAddress);

                    cloudbe.Identity = Encoding.Unicode.GetBytes(myself);
                    for (int arg = 1; arg < args.Length; arg++)
                    {
                        var endpoint = "tcp://127.0.0.1:" + args[arg];
                        peers.Add(endpoint);
                        Console.WriteLine("I: connecting to cloud frontend at " + endpoint);
                        cloudbe.Connect(endpoint);
                    }

                    localFeAddress = cloudFeAddress + "1";
                    localfe.Bind(localFeAddress);
                    localBeAddress = cloudFeAddress + "2";
                    localbe.Bind(localBeAddress);

                    Console.WriteLine("Press Enter when all brokers are started: ");
                    Console.ReadKey();

                    var workers = new List<Thread>();
                    for (int workerNumber = 0; workerNumber < numberOfWorkers; workerNumber++)
                    {
                        workers.Add(new Thread(WorkerTask));
                        workers[workerNumber].Start();
                    }

                    var clients = new List<Thread>();
                    for (int clientNumber = 0; clientNumber < numberOfClients; clientNumber++)
                    {
                        clients.Add(new Thread(ClientTask));
                        clients[clientNumber].Start();
                    }

                    var workerQueue = new Queue<byte[]>();

                    var localfeReady = false;
                    var cloudfeReady = false;

                    var backends = new PollItem[2];
                    backends[0] = localbe.CreatePollItem(IOMultiPlex.POLLIN);
                    backends[0].PollInHandler += (socket, revents) =>
                                                     {
                                                         var zmsg = new ZMessage(socket);

                                                         //  Use worker address for LRU routing
                                                         workerQueue.Enqueue(zmsg.Unwrap());

                                                         if (zmsg.BodyToString() != "READY")
                                                         {
                                                             SendReply(zmsg, cloudfe, localfe);
                                                         }
                                                     };

                    backends[1] = cloudbe.CreatePollItem(IOMultiPlex.POLLIN);
                    backends[1].PollInHandler += (socket, revents) =>
                    {
                        var zmsg = new ZMessage(socket);
                        //  We don't use peer broker address for anything
                        zmsg.Unwrap();

                        SendReply(zmsg, cloudfe, localfe);
                    };

                    var frontends = new PollItem[2];
                    frontends[0] = cloudfe.CreatePollItem(IOMultiPlex.POLLIN);
                    frontends[0].PollInHandler += (socket, revents) =>
                                                    {
                                                        cloudfeReady = true;
                                                    };

                    frontends[1] = localfe.CreatePollItem(IOMultiPlex.POLLIN);
                    frontends[1].PollInHandler += (socket, revents) =>
                                                     {
                                                         localfeReady = true;
                                                     };

                    while (true)
                    {
                        var timeout = (workerQueue.Count > 0 ? 1000000 : -1);
                        var rc = Context.Poller(backends, timeout);

                        if (rc == -1)
                            break; // Interrupted

                        while (workerQueue.Count > 0)
                        {
                            Context.Poller(frontends, 0);
                            bool reRoutable;

                            ZMessage msg;

                            if (cloudfeReady)
                            {
                                cloudfeReady = false;
                                msg = new ZMessage(cloudfe);
                                reRoutable = false;
                            }
                            else if (localfeReady)
                            {
                                localfeReady = false;
                                msg = new ZMessage(localfe);
                                reRoutable = true;
                            }
                            else
                            {
                                break;
                            }

                            //if (reRoutable && workerQueue.Count > 0 && randomizer.Next(3) == 0)
                            if (reRoutable && peers.Count > 0 && randomizer.Next(4) == 0)
                            {
                                var randomPeer = randomizer.Next(1, args.Length - 1);
                                var endpoint = "tcp://127.0.0.1:" + args[randomPeer];
                                msg.Wrap(Encoding.Unicode.GetBytes(endpoint), new byte[0]);
                                msg.Send(cloudbe);
                            }
                            else
                            {
                                msg.Wrap(workerQueue.Dequeue(), new byte[0]);
                                msg.Send(localbe);
                            }
                        }
                    }
                }
            }
        }
예제 #7
0
파일: peering2.cs 프로젝트: hnkien/zguide2
        private static void WorkerTask()
        {
            using (var ctx = new Context(1))
            {
                using (var worker = ctx.Socket(SocketType.REQ))
                {
                    ZHelpers.SetID(worker, Encoding.Unicode);
                    worker.Connect(localBeAddress);

                    var msg = new ZMessage("READY");
                    msg.Send(worker);

                    while (true)
                    {
                        var recvMsg = new ZMessage(worker);
                        Console.WriteLine("Worker: {0}", recvMsg.BodyToString());

                        Thread.Sleep(1000);

                        recvMsg.StringToBody("OK");
                        recvMsg.Send(worker);
                        //var okmsg = new ZMessage("OK");
                        //okmsg.Send(worker);
                    }
                }
            }
        }
예제 #8
0
파일: peering2.cs 프로젝트: hnkien/zguide2
        private static void SendReply(ZMessage msg, Socket cloudfe, Socket localfe)
        {
            var address = Encoding.Unicode.GetString(msg.Address);
            //  Route reply to cloud if it's addressed to a broker

            if (peers.Count(peerAddress => peerAddress == address) == 1)
            {
                Console.WriteLine("Sending to cloud frontend");
                msg.Send(cloudfe);
            }
            else
            {
                Console.WriteLine("Sending to local frontend");
                msg.Send(localfe);
            }
        }