示例#1
0
        public void Launch(Action <Exception> done)
        {
            if (_task != null && !_task.IsCompleted)
            {
                throw new InvalidOperationException($"Can't launch {Id} while previous instance is {_task.Status}");
            }

            var procID = _machine.NextProcID();
            var env    = new SimProc(Id, _machine, procID, _factory);

            _task = _factory.StartNew(async() => {
                try {
                    var engine = _launcher(env);
                    try {
                        await engine.Run();
                    } finally {
                        await engine.Dispose();
                    }
                } catch (AggregateException ex) {
                    done(ex.InnerException);
                    return;
                }
                catch (Exception ex) {
                    done(ex);
                    return;
                }

                done(null);
            }).Unwrap();
            _proc = env;
        }
示例#2
0
        public SimConn(SimSocket socket, SimEndpoint remoteAddress, SimProc proc, uint seq, uint ackNumber)
        {
            _socket       = socket;
            RemoteAddress = remoteAddress;
            _proc         = proc;

            _sequenceNumber = seq;
            _ackNumber      = ackNumber;
        }
示例#3
0
        public void ReleaseResources()
        {
            if (_proc != null)
            {
                _proc.Dispose();
                _proc = null;
            }

            _task = null;
        }
示例#4
0
        public async Task <IConn> Connect(SimProc process, SimEndpoint destination)
        {
            SimRoute route;

            if (!Cluster.TryGetRoute(Name, destination.Machine, out route))
            {
                throw new IOException($"Route not found");
            }


            // todo: allocate port
            // todo: allow Azure SNAT delay scenario
            var socketId     = NextSocketID();
            var source       = new SimEndpoint(Name, socketId);
            var clientSocket = new SimSocket(process, source, Cluster);

            try {
                _sockets.Add(socketId, clientSocket);


                var conn = new SimConn(clientSocket, destination, process, 0, 0);

                clientSocket._connections.Add(destination, conn);


                // handshake
                await conn.Write(null, SimFlag.Syn);

                var response = await conn.Read(5.Sec());

                if (response.Flag != (SimFlag.Ack | SimFlag.Syn))
                {
                    Debug(LogType.Warning, $"Bad handshake: {response.BodyString()}");
                    await conn.Write(null, SimFlag.Reset);

                    clientSocket._connections.Remove(destination);
                    throw new IOException($"Failed to connect (got {response.BodyString()})");
                }

                await conn.Write(null, SimFlag.Ack);

                return(new ClientConn(conn));
            } catch (IOException) {
                throw;
            }
            catch (Exception ex) {
                _sockets.Remove(socketId);
                clientSocket.Dispose();
                throw new IOException($"Failed to connect: {ex.Message}", ex);
            }
        }
示例#5
0
        public async Task <ISocket> Bind(SimProc proc, ushort port, TimeSpan timeout)
        {
            // socket is bound to the owner
            var endpoint = new SimEndpoint(proc.Id.Machine, port);

            if (_sockets.ContainsKey(port))
            {
                throw new IOException($"Address {endpoint} in use");
            }

            var socket = new SimSocket(proc, endpoint, Cluster);

            _sockets.Add(port, socket);

            proc.RegisterSocket(socket);

            return(socket);
        }
示例#6
0
 public SimSocket(SimProc proc, SimEndpoint endpoint, SimCluster net)
 {
     _proc    = proc;
     Endpoint = endpoint;
     _net     = net;
 }