private void Heartbeating(object state) { var ctx = (ChannelHandlerContext)state; if (!ctx.Channel.IsOpen) { return; } var currentTime = Convenient.CurrentTimeMillis(); var lastIoTime = Math.Max(_lastReadTime.Get(), _lastWriteTime.Get()); var nextDelay = TimeToHeartBeatMillis - (currentTime - lastIoTime); if (_peerConnection != null && nextDelay <= 0) { Logger.Debug("Sending heart beat to {0}. Channel: {1}.", _peerConnection.RemotePeer, _peerConnection.Channel); var builder = _pingBuilderFactory.Create(); var taskPing = builder.SetPeerConnection(_peerConnection).Start(); builder.NotifyAutomaticFutures(taskPing); } else { // TODO fix possible NPE Logger.Debug("Not sending heart beat to {0}. Channel: {1}.", _peerConnection.RemotePeer, _peerConnection.Channel); } }
public override async Task DoReceiveMessageAsync() { // receive bytes UdpReceiveResult udpRes; try { udpRes = await _udpClient.ReceiveAsync().WithCancellation(CloseToken); } catch (OperationCanceledException) { // the socket has been closed return; } var buf = AlternativeCompositeByteBuf.CompBuffer(); buf.WriteBytes(udpRes.Buffer.ToSByteArray()); var localEp = (IPEndPoint)Socket.LocalEndPoint; RemoteEndPoint = udpRes.RemoteEndPoint; var dgram = new DatagramPacket(buf, localEp, RemoteEndPoint); Logger.Debug("Received {0}. {1} : {2}", dgram, Convenient.ToHumanReadable(udpRes.Buffer.Length), Convenient.ToString(udpRes.Buffer)); // execute inbound pipeline if (Session.IsTimedOut) { return; } Session.Read(dgram); Session.Reset(); }
public void CheckTimeout() { var time = Convenient.CurrentTimeMillis(); var toRemove = _backend.SubMapTimeout(time); foreach (var key in toRemove) { var rangeLock = Lock(key); try { _backend.Remove(key, false); _backend.RemoveTimeout(key); // remove responsibility if we don't have any data stored under locationkey var locationKey = key.LocationKey; var lockResp = LockResponsibility(locationKey); try { if (IsEmpty(locationKey)) { _backend.RemoveResponsibility(locationKey); } } finally { lockResp.Unlock(); } } finally { rangeLock.Unlock(); } } }
/// <summary> /// This does not reset the timer! /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public TValue PutIfAbsent(TKey key, TValue value) { var newValue = new ExpiringObject(value, Convenient.CurrentTimeMillis(), _timeToLiveSeconds); var segment = Segment(key); ExpiringObject oldValue; lock (segment) { if (!segment.ContainsKey(key)) { oldValue = segment.Add(key, newValue); } else { oldValue = segment.Get(key); if (oldValue.IsExpired) { segment.Add(key, newValue); } else if (_refreshTimeout) { oldValue = new ExpiringObject(oldValue.Value, Convenient.CurrentTimeMillis(), _timeToLiveSeconds); segment.Add(key, oldValue); } } } if (oldValue == null || oldValue.IsExpired) { return(null); } return(oldValue.Value); }
/// <summary> /// Bootstraps to the given peer addresses. I.e., looking for near nodes. /// </summary> /// <param name="peerAddresses">The node to which bootstrap should be performed to.</param> /// <param name="routingBuilder">All relevant information for the routing process.</param> /// <param name="cc">The channel creator.</param> /// <returns>A task object that is set to complete if the route has been found.</returns> public Task <Pair <TcsRouting, TcsRouting> > Bootstrap(ICollection <PeerAddress> peerAddresses, RoutingBuilder routingBuilder, ChannelCreator cc) { // search close peers Logger.Debug("Bootstrap to {0}.", Convenient.ToString(peerAddresses)); var tcsDone = new TaskCompletionSource <Pair <TcsRouting, TcsRouting> >(); // first, we find close peers to us routingBuilder.IsBootstrap = true; var tcsRouting0 = Routing(peerAddresses, routingBuilder, Message.Message.MessageType.Request1, cc); // we need to know other peers as well // this is important if this peer is passive and only replies on requests from other peers tcsRouting0.Task.ContinueWith(taskRouting0 => { if (!taskRouting0.IsFaulted) { // setting this to null causes to search for a random number routingBuilder.LocationKey = null; var tcsRouting1 = Routing(peerAddresses, routingBuilder, Message.Message.MessageType.Request1, cc); tcsRouting1.Task.ContinueWith(taskRouting1 => { var pair = new Pair <TcsRouting, TcsRouting>(tcsRouting0, tcsRouting1); tcsDone.SetResult(pair); }); } else { tcsDone.SetException(taskRouting0.TryGetException()); } }); return(tcsDone.Task); }
private void AllIdleTimeoutTask(object state) { var ctx = state as ChannelHandlerContext; // .NET-specific: don't fire if session is already set to timed out if (ctx == null || !ctx.Channel.IsOpen || ctx.IsTimedOut) { return; } long currentTime = Convenient.CurrentTimeMillis(); long lastIoTime = Math.Max(_lastReadTime.Get(), _lastWriteTime.Get()); long nextDelay = (AllIdleTimeMillis - (currentTime - lastIoTime)); if (nextDelay <= 0) { // both reader and writer are idle // --> set a new timeout and notify the callback //Logger.Debug("Both reader and writer are idle..."); _cts = _executor.Schedule(AllIdleTimeoutTask, ctx, AllIdleTimeMillis); try { ctx.FireUserEventTriggered(this); } catch (Exception ex) { ctx.FireExceptionCaught(ex); } } else { // either read or write occurred before the timeout // --> set a new timeout with shorter delayMillis _cts = _executor.Schedule(AllIdleTimeoutTask, ctx, nextDelay); } }
/// <summary> /// Creates an empty Data object. The data can be filled at a later stage. /// </summary> /// <param name="header">The 8 bit header.</param> /// <param name="length">The length, depending on the header values.</param> public Data(int header, int length) { HasPublicKey = CheckHasPublicKey(header); IsFlag1 = CheckIsFlag1(header); IsFlag2 = CheckIsFlag2(header); _basedOnFlag = CheckHasBasedOn(header); IsSigned = CheckIsSigned(header); _ttl = CheckHasTtl(header); IsProtectedEntry = CheckIsProtectedEntry(header); _type = Type(header); HasPrepareFlag = CheckHasPrepareFlag(header); if (_type == DataType.Small && Length > 255) { throw new ArgumentException("DataType is small, but should be large."); } else if (_type == DataType.Large && (Length <= 255)) { throw new ArgumentException("DataType is large, but should be small."); } Length = length; _buffer = new DataBuffer(); ValidFromMillis = Convenient.CurrentTimeMillis(); TtlSeconds = -1; BasedOnSet = new List <Number160>(0); }
/// <summary> /// Indicates if a peer needs a maintenance check. /// </summary> /// <param name="peerStatistic">The peer with its statistics.</param> /// <param name="intervalSeconds"></param> /// <returns>True, if the peer needs a maintenance check.</returns> public static bool NeedMaintenance(PeerStatistic peerStatistic, int[] intervalSeconds) { int onlineSec = peerStatistic.OnlineTime / 1000; int index; if (onlineSec <= 0) { index = 0; } else { index = intervalSeconds.Length - 1; for (int i = 0; i < intervalSeconds.Length; i++) { if (intervalSeconds[i] >= onlineSec) { index = i; break; } } } int time = intervalSeconds[index]; long lastTimeWhenChecked = Convenient.CurrentTimeMillis() - peerStatistic.LastSeenOnline; return(lastTimeWhenChecked > TimeSpan.FromSeconds(time).TotalSeconds); }
private void Initialize(ChannelHandlerContext ctx) { switch (_state) { case 1: return; case 2: return; } _state = 1; // .NET-specific: if (_executor == null) { _executor = new ExecutorService(); } var currentMillis = Convenient.CurrentTimeMillis(); _lastReadTime.Set(currentMillis); _lastWriteTime.Set(currentMillis); if (AllIdleTimeMillis > 0) { _cts = _executor.Schedule(AllIdleTimeoutTask, ctx, AllIdleTimeMillis); } }
public override async Task SendBytesAsync(byte[] bytes, IPEndPoint senderEp, IPEndPoint receiverEp = null) { // send bytes await _udpClient.SendAsync(bytes, bytes.Length, receiverEp); Logger.Debug("Sent UDP: Sender {0} --> Recipient {1}. {2} : {3}", senderEp, receiverEp, Convenient.ToHumanReadable(bytes.Length), Convenient.ToString(bytes)); }
private void DiscoverTimeoutTask(object state) { var serverPeerAddress = state as PeerAddress; string msg = String.Format("Timeout in discover: {0}ms. However, I think my peer address is {1}.", Convenient.CurrentTimeMillis() - _start, serverPeerAddress); Failed(serverPeerAddress, msg); }
public override async Task SendBytesAsync(byte[] bytes, IPEndPoint senderEp, IPEndPoint receiverEp = null) { // send bytes var recvEp = _tcpClient.Client.RemoteEndPoint; await _tcpClient.GetStream().WriteAsync(bytes, 0, bytes.Length); Logger.Debug("Sent TCP: Sender {0} --> Recipient {1}. {2} : {3}", senderEp, recvEp, Convenient.ToHumanReadable(bytes.Length), Convenient.ToString(bytes)); }
/// <summary> /// Creates a Data object that does have the complete data, but not the complete header. /// </summary> /// <param name="buffer">The buffer containing the data.</param> /// <param name="length">The expected length of the buffer. This does not include the header + size (2, 5 or 9).</param> public Data(DataBuffer buffer, int length) { Length = length; _type = Length < MaxByteSize ? DataType.Small : DataType.Large; _buffer = buffer; ValidFromMillis = Convenient.CurrentTimeMillis(); TtlSeconds = -1; BasedOnSet = new List <Number160>(0); }
public Buffer Reply(PeerAddress sender, Buffer requestBuffer, bool complete) { Console.WriteLine("{0}.", ++_counter); Console.WriteLine("Request from {0}.", sender); Console.WriteLine("Buffer Size : {0}", Convenient.ToHumanReadable(requestBuffer.Length)); // server returns just OK if same buffer is returned return(requestBuffer); }
/// <summary> /// Creates a new future object and creates a timer that fires failed after a timeout. /// </summary> /// <param name="serverPeerAddress"></param> /// <param name="timer">.NET-specific: CTS instead of timer.</param> /// <param name="delaySec">The delay in seconds.</param> public void Timeout(PeerAddress serverPeerAddress, ExecutorService timer, int delaySec) { _start = Convenient.CurrentTimeMillis(); var cts = timer.Schedule(DiscoverTimeoutTask, serverPeerAddress, TimeSpan.FromSeconds(delaySec).TotalMilliseconds); // ReSharper disable once MethodSupportsCancellation // cancel timeout if we are done Task.ContinueWith(tDelay => cts.Cancel()); }
public PeerStatistic(PeerAddress peerAddress) { if (peerAddress == null) { throw new ArgumentException("PeerAddress cannot be null."); } Created = Convenient.CurrentTimeMillis(); _peerId = peerAddress.PeerId; PeerAddress = peerAddress; }
public override string ToString() { var sb = new StringBuilder("paddr["); return(sb.Append(PeerId) .Append(PeerSocketAddress) .Append("]/relay(").Append(IsRelayed) .Append(",").Append(PeerSocketAddresses.Count) .Append(")=").Append(Convenient.ToString(PeerSocketAddresses)) .ToString()); }
public async void TestPingTimeUdp() { Peer sender = null; Peer recv1 = null; try { sender = new PeerBuilder(new Number160("0x9876")) .SetP2PId(55) .SetPorts(2424) .Start(); recv1 = new PeerBuilder(new Number160("0x9876")) .SetP2PId(55) .SetPorts(8088) .Start(); long start = Convenient.CurrentTimeMillis(); var tasks = new List <Task <Message> >(1000); for (int i = 0; i < 20; i++) { var cc = await recv1.ConnectionBean.Reservation.CreateAsync(50, 0); for (int j = 0; j < 50; j++) { var taskResponse = sender.PingRpc.PingUdpAsync(recv1.PeerAddress, cc, new DefaultConnectionConfiguration()); tasks.Add(taskResponse); } foreach (var task in tasks) { await task; Assert.IsTrue(!task.IsFaulted); } tasks.Clear(); await cc.ShutdownAsync(); } Console.WriteLine("UDP time: {0}ms.", Convenient.CurrentTimeMillis() - start); } finally { if (sender != null) { sender.ShutdownAsync().Wait(); } if (recv1 != null) { recv1.ShutdownAsync().Wait(); } } }
private void EncodeData(AlternativeCompositeByteBuf buffer, Data data, bool isConvertMeta, bool isReply) { data = isConvertMeta ? data.DuplicateMeta() : data.Duplicate(); if (isReply) { var ttl = (int)((data.ExpirationMillis - Convenient.CurrentTimeMillis()) / 1000); data.SetTtlSeconds(ttl < 0 ? 0 : ttl); } data.EncodeHeader(buffer, _signatureFactory); data.EncodeBuffer(buffer); data.EncodeDone(buffer, _signatureFactory, Message.PrivateKey); }
public IList <ByteBuf> Decompose(int offset, int length) { CheckIndex(offset, length); if (length == 0) { return(Convenient.EmptyList <ByteBuf>()); } int componentId = FindIndex(offset); IList <ByteBuf> slice = new List <ByteBuf>(_components.Count); // the first component var firstC = _components[componentId]; var first = firstC.Buf.Duplicate(); first.SetReaderIndex(offset - firstC.Offset); ByteBuf buf = first; int bytesToSlice = length; do { int readableBytes = buf.ReadableBytes; if (bytesToSlice <= readableBytes) { // last component buf.SetWriterIndex(buf.ReaderIndex + bytesToSlice); slice.Add(buf); break; } else { // not the last component slice.Add(buf); bytesToSlice -= readableBytes; componentId++; // fetch the next component buf = _components[componentId].Buf.Duplicate(); } } while (bytesToSlice > 0); // slice all component because only readable bytes are interesting for (int i = 0; i < slice.Count; i++) { slice[i] = slice[i].Slice(); } return(slice); }
protected override async Task ProcessRequestAsync(object state) { var udpRes = (UdpReceiveResult)state; // prepare new session var buf = AlternativeCompositeByteBuf.CompBuffer(); var session = Pipeline.CreateNewServerSession(this); session.TriggerActive(); // process content buf.WriteBytes(udpRes.Buffer.ToSByteArray()); var localEp = (IPEndPoint)_udpClient.Client.LocalEndPoint; var remoteEp = udpRes.RemoteEndPoint; var dgram = new DatagramPacket(buf, localEp, remoteEp); Logger.Debug("Received {0}. {1} : {2}", dgram, Convenient.ToHumanReadable(udpRes.Buffer.Length), Convenient.ToString(udpRes.Buffer)); // execute inbound pipeline var readRes = session.Read(dgram); // resets timeout if (session.IsTimedOut) { session.TriggerInactive(); return; } // execute outbound pipeline var writeRes = session.Write(readRes); // resets timeout if (session.IsTimedOut) { session.TriggerInactive(); return; } // send back var bytes = ConnectionHelper.ExtractBytes(writeRes); await _udpClient.SendAsync(bytes, bytes.Length, remoteEp); NotifyWriteCompleted(); // resets timeout Logger.Debug("Sent {0} : {1}", Convenient.ToHumanReadable(udpRes.Buffer.Length), Convenient.ToString(udpRes.Buffer)); session.TriggerInactive(); }
/// <summary> /// Creates a Data object from an already existing buffer. /// </summary> /// <param name="buffer"></param> /// <param name="offset"></param> /// <param name="length"></param> public Data(sbyte[] buffer, int offset, int length) { if (buffer.Length == 0) { _buffer = new DataBuffer(0); } else { _buffer = new DataBuffer(buffer, offset, length); } Length = length; _type = Length < MaxByteSize ? DataType.Small : DataType.Large; ValidFromMillis = Convenient.CurrentTimeMillis(); TtlSeconds = -1; BasedOnSet = new List <Number160>(0); }
public TValue Put(TKey key, TValue value) { var newValue = new ExpiringObject(value, Convenient.CurrentTimeMillis(), _timeToLiveSeconds); var segment = Segment(key); ExpiringObject oldValue; lock (segment) { oldValue = segment.Add(key, newValue); } if (oldValue == null || oldValue.IsExpired) { return(null); } return(oldValue.Value); }
public override async Task DoReceiveMessageAsync() { // TODO find zero-copy way, use same buffer // receive bytes var bytesRecv = new byte[256]; var buf = AlternativeCompositeByteBuf.CompBuffer(); var stream = _tcpClient.GetStream(); var pieceCount = 0; do { Array.Clear(bytesRecv, 0, bytesRecv.Length); buf.Clear(); int nrBytes; try { nrBytes = await stream.ReadAsync(bytesRecv, 0, bytesRecv.Length).WithCancellation(CloseToken); } catch (OperationCanceledException) { // the socket has been closed return; } buf.WriteBytes(bytesRecv.ToSByteArray(), 0, nrBytes); var localEp = (IPEndPoint)Socket.LocalEndPoint; RemoteEndPoint = (IPEndPoint)Socket.RemoteEndPoint; var piece = new StreamPiece(buf, localEp, RemoteEndPoint); Logger.Debug("[{0}] Received {1}. {2} : {3}", ++pieceCount, piece, Convenient.ToHumanReadable(nrBytes), Convenient.ToString(bytesRecv)); // execute inbound pipeline, per piece (reset session!) if (Session.IsTimedOut) { return; } Session.Read(piece); Session.Reset(); } while (!IsClosed && stream.DataAvailable && !Session.IsTimedOut); }
public ICollection <Number160> FindContentForResponsiblePeerId(Number160 peerId) { var lockResp = LockResponsibility(peerId); try { var contentIds = _backend.FindContentForResponsiblePeerId(peerId); if (contentIds == null) { return(Convenient.EmptyList <Number160>()); } else { return(new List <Number160>(contentIds)); } } finally { lockResp.Unlock(); } }
public override MemoryStream NioBuffer(int index, int length) { if (_components.Count == 1) { var buf = _components[0].Buf; if (buf.NioBufferCount() == 1) { return(_components[0].Buf.NioBuffer(index, length)); } } var merged = Convenient.Allocate(length); // little-endian var buffers = NioBuffers(index, length); for (int i = 0; i < buffers.Length; i++) { merged.Put(buffers[i]); } merged.Flip(); return(merged); }
public bool Replace(TKey key, TValue oldValue, TValue newValue) { var oldValue2 = new ExpiringObject(oldValue, 0, _timeToLiveSeconds); var newValue2 = new ExpiringObject(newValue, Convenient.CurrentTimeMillis(), _timeToLiveSeconds); var segment = Segment(key); ExpiringObject oldValue3; bool replaced = false; lock (segment) { oldValue3 = segment.Get(key); if (oldValue3 != null && !oldValue3.IsExpired && oldValue2.Value.Equals(oldValue3.Value)) { segment.Add(key, newValue2); replaced = true; } } if (oldValue3 != null) { Expire(segment, key, oldValue3); } return(replaced); }
private void Initialize(ChannelHandlerContext ctx) { switch (_state) { case 1: return; case 2: return; } _state = 1; // .NET-specific: if (_executor == null) { _executor = new ExecutorService(); } var currentMillis = Convenient.CurrentTimeMillis(); _lastReadTime.Set(currentMillis); _lastWriteTime.Set(currentMillis); _timer = _executor.ScheduleAtFixedRate(Heartbeating, ctx, TimeToHeartBeatMillis, TimeToHeartBeatMillis); }
public UnpooledDirectByteBuf(IByteBufAllocator alloc, int initialCapacity, int maxCapacity) : base(maxCapacity) { if (alloc == null) { throw new NullReferenceException("alloc"); } if (initialCapacity < 0) { throw new ArgumentException("initialCapacity: " + initialCapacity); } if (maxCapacity < 0) { throw new ArgumentException("maxCapacity: " + maxCapacity); } if (initialCapacity > maxCapacity) { throw new ArgumentException(String.Format( "initialCapacity({0}) > maxCapacity({1})", initialCapacity, maxCapacity)); } _alloc = alloc; SetByteBuffer(Convenient.AllocateDirect(initialCapacity)); }
public override void Write(ChannelHandlerContext ctx, object msg) { ctx.Channel.WriteCompleted += channel => _lastWriteTime.Set(Convenient.CurrentTimeMillis()); //ctx.FireWrite(msg); // TODO needed? }