Coder Social home page Coder Social logo

mucaho / jnetrobust Goto Github PK

View Code? Open in Web Editor NEW
23.0 7.0 0.0 773 KB

Fast, reliable & non-intrusive message-oriented virtual network protocol for Java 6+.

License: Mozilla Public License 2.0

Java 100.00%
java java6 network-protocol message-oriented reliable-udp reliability udp protocol networking messaging

jnetrobust's People

Contributors

mkucko avatar mucaho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

jnetrobust's Issues

Question on library suitability

Is this library suitable for high latency and unreliable network connections?

How is reliability accomplished? Is it an ACK or a NACK based system?

Improve performance

As this library is also intended to work on Android, performance should be optimized where applicable

  • send only 1 packet (no duplicate ack/last ack fields) for multiple for retransmits
    -> add Controller.send(Collection<MultiKeyValue>): Packet
    -> add Controller.receive(Packet with Collection<MultiKeyValue>): Object
  • make sure that there is minimal object allocation inside scopes -> extract such local variables as fields
  • add object pools for Packet, MultiKeyValue, Iterator and co instead of instantiating new objects
    -> update serializer object creation strategy to use object pools
  • use practical initialCapacity parameters during collection initialization
  • use a rolling fixed size queue for pending acks, eg. a 256 size queue indexed by sequence number mod 256. changing to plain array much of the NavigableMap functionality is lost -> rather investigate alternative collection libraries with near zero garbage

Add congestion avoidance

Currently only basic congestion control is done when retransmitting packets. No congestion control is performed when sending new packets.

The problem is that the application is "in control", as it pushes/pulls data to/from the protocol. The protocol should not delay sending of packets due to highly congested network; It should inform the application about the current status of network congestion and let the application decide how much to throttle amount of data / rate of data that is being send. (e.g. Protocol.getCongestionFactor(): double -> if its greater than 1, application could send more data -> if its less than 1, application could send less data).

Investigate existing congestion control algorithms - look at their characteristics
preferably use the ones which do not send extra metadata about network congestion; preferably use the ones that consider RTT, RTT variance, (estimated) packet loss, the form of the lastTransmissionAcks field and the offset from sender side transmissionId and received transmissionAck (as well as the history of this offset - mean/deviation); preferably use the ones which are a bit more aggressive:

Notes on form of the lastTransmissionAcks vector field:
vector v
v[i] = {0, 1} ... 0 = acked, 1= notAcked
i โ‚ฌ {0, n}, 0 is most recent, n is oldest transmissionAck:

  • weightingFactor = #{i: v[i] = 0} / n ... the more notAcked, the greater the factor
  • sum_1 = sum(i: 0..n) v[i] * log(n/i) <=> v[i] != v[i+1] .... most recent not acked carry most weight
  • sum_2 = sum(i: 0..n) v[i] * log(n/i) * v[i+1] * log(n/i) <=> v[i] == v[i+1] ... the greater a continuous gap of not acked, the multiplicative more weight it has
  • score = (sum_1 + sum_2) * weightingFactor

Investigate fast retransmit -> resend packets that are missing in lastAcks field: this could work if we send at @ 10 Hz (every 100ms), but does not make sense if we send @ 120 Hz (every 9 ms), as due to jitter many packets get send before the out of order packet arrives -> ADDED

Benchmark performance

Benchmark the performance (latency, throughput, protocol overhead) vs TCP in multiple combinations of following factors:

  • discrete data packets vs unending stream of data
  • bidirectional vs unidirectional communication
  • @ 10 Hz, @ 30Hz, @ 60Hz, continuous communication
  • ideal vs normal vs worst-nightmare network conditions
  • constant network conditions vs spikes of different network conditions

Make sure to benchmark also on real connection over INet

Mavenize the project

  • Add maven goals for compiling, running, deploying, testing, etc
  • Either publish the artifacts & repositories of JArrayLiterals & Java UDP Wan Emulator to GitHub OR submit to maven central and -> then add dependency to JArrayLiterals & Java UDP Wan Emulator
  • Follow the Sonatype Guidelines to enable automatic publishing of JNetRobust

Add example

Add a fully-fledged example (using Kryo serializer and DatagramSockets) to showcase usage. Make sure to include multiple protocol instances between the two hosts (add protocolId field).

  • add a DefaultHost which configures most of the stuff automatically (with DatagramChannel, Buffer, and default behaviour for protocol - show only received and ordered, throw Exception if very bad network conditions, e.g. packet retransmitted 5 times or pendingMap/receivedMap too full)
  • Server, ClientA, ClientB: Clients route through Server, display different data deliveries between hosts, also use 60 Hz bidirectional communication for ClientA <-> Server, and on-demand communication between ClientB <-> Server
  • Add also simple example that just sends 1 message (utilizes DefaultHost)

Split API & implementation

Make sure the user can only access API and not access or modify inner workings: (e.g. Packet.setData)

  • rename packages & split code into api / implementation
  • provide proper visibility of api and implementation classes

Add additional documentation

Add documentation:

  • explain ProtocolListener.handleUnordered better (it's actually unreceived data that gets skipped over, the argument is the first data after the "gap")
  • document jnetrobust-samples
  • document Packet & MetaData
  • rename MetaData to Segment, to be in line with ISO/OSI terminology analogue to Packet, update Wiki
  • document non API classes
  • explain Config values better and which listener gets called once constraint violated
  • explain Protocol empty ack transmission requirement better. Use RTT and packet send rate.
  • add pseudocode diagram for using protocol methods
  • move javadoc to github pages
  • give overview of project in readme file
  • provide API overview in wiki
  • document that user is required to send ACK immediately with empty transmission, unless he is sending packets at fixed intervals < 100 ms
  • inform user that if he uses protocol without retransmission, he should adapt config values to be more aggressive so he is informed a lot quicker about lost/unordered packets -> 16 should be fine

Add additional tests

Add additional tests to improve test coverage:

  • investigate if old incoming messages (> 2 min) get dropped correctly, check for their difference with current ids (dataId & transmissionId), if id_diff > RANGE / 4 then drop & test that
  • investigate if there is an off-by-1 error when reaching max retransmit MetaDatas in packet & test that
  • add tests for Controller (data & packet as input)
  • test ReceivedMapControl.removeEntry as its not trivial
  • implement SimpleMapControlTest.testDiscardTimedoutEntries & SimpleMapControlTest.testDiscardEntryTooOften
  • add int to long test to PrimitiveValuesTest
  • check if pendingMapSize & receivedMapSize is empty in DelayedTest
  • test empty retransmits (unidirectional communication)
  • although Protocol's methods are synchronized, the returned collections are not and could be modified in between method calls, test this
  • extend WanEmulator to simulate lag spikes where every packet gets dropped for a period of time

NPE during modified unit test

[0] 40, 60000, 0.75, 0.25, 16, 1000, true (testDelayed)(com.github.mucaho.jnetrobust.DelayedTest)  Time elapsed: 1,472.111 sec  <<< ERROR!
java.lang.NullPointerException
    at com.github.mucaho.jnetrobust.controller.Controller.receive(Controller.java:92)
    at com.github.mucaho.jnetrobust.controller.Controller.receive(Controller.java:86)
    at com.github.mucaho.jnetrobust.util.TestHost.consume(TestHost.java:73)
    at com.github.mucaho.jnetrobust.util.TestHost.receive(TestHost.java:64)
    at com.github.mucaho.jnetrobust.util.TestHost.receive(TestHost.java:59)
    at com.github.mucaho.jnetrobust.DelayedTest.testDelayed(DelayedTest.java:202)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at junitparams.internal.InvokeParameterisedMethod.evaluate(InvokeParameterisedMethod.java:209)
    at junitparams.internal.ParameterisedTestMethodRunner.runMethodInvoker(ParameterisedTestMethodRunner.java:49)
    at junitparams.internal.ParameterisedTestMethodRunner.runTestMethod(ParameterisedTestMethodRunner.java:42)
    at junitparams.internal.ParameterisedTestClassRunner.runParameterisedTest(ParameterisedTestClassRunner.java:143)
    at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:393)
    at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:371)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

Refactor code

  • let PendingMapControl.removeFromPending work with long as lastAck parameter -> also use BitConstants.convert to convert between int and lng
  • Return set list interface for retransmits
  • allow sending of multiple datas & metadatas protocol.send(T... datas)
  • changeadd Protocol.compare(id1, id2) to static method
  • consider returning Id opaque handles instead of shorts wontfix for now unless java supports zero overhead typedefs
  • add setters & documentation for K and G RTO parameters
  • rename MetaData.lastTimeTouched to lastTimeTransmitted
  • make ordered packet fields optional, split ordered handling into new Controller, MetaData & Packet, use CRTP generics wontfix for now since serialization supports only static config options (no way to pass parameters to methods of Serializable interface)
  • check if fully 1.6 compliant (especially samples - Datagramchannel socket creation)
  • ProtocolHost - add udp traffic class hints
  • ProtocolHost - use allocateDirect for buffers only worth it if Java code writes less to buffers than native IO/net system, in the examples server always writes more data to clients than receiving, because it's server + other client data that gets sent from server
  • add DefaultHost.register(SocketAddress, DataClass) which instantiates new Protocol instance for that address -> actually also allow adding multiple protocol instances per SocketAddress to allow one instance with transmission and one w/o -> reuse serialization and network channel -> do multiplexing based on first byte protocold to (receive) & based on SocketAddress-to-send (send) to different Protocol instances -> adapt Synchronization example to work with this -> no need to use protocolId, just use different ports
  • remove type parameter from ProtocolHost, as different ProtocolHandles can have different user datas; figure out how to guarantee same order of UserData.class kryo serialization registrations on multiple hosts
  • relay received data in ServerSynchronizationController after ordering or only newest instead?
  • add UPDATE_ON_INTERPOLATED_DATA (interpol_rcvd &&/|| interpol_nwst &&|| interpol_ord) to Synchronization example may be overkill for now, though could be integrated into another fully-fledged example showcasing client connection / disconnection management
  • add handleRetransmitData to ProtocolListener
  • if shouldRetransmit is true then it reports already retransmitted data
  • if shouldRetransmit is false then it's up to the application whether to retransmit or not
  • rename shouldRetransmit to autoRetransmit
  • pass listener as separate parameter to constructor, as config is optional
  • report unAcked data on RTO, truthy return value from listener indicates to retransmit, defaults to true, may supply additional info to listener superseded by new retransmit logic
  • report unOrdered data on RTO * factor. truthy return value from listener indicates to skip over this data, may supply additional info to listener superseded by new retransmit logic
  • let application decide if it wants to retransmit packets -> either make 2 protocol instances and tell one of those to not bother with retransmission -> or add boolean flag to each data informing about importance of data -> also add example for that
  • add API and implementation javadoc tags to differentiate between the 2 in javadocs

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.