{"action":"created","issue":{"url":"https://api.github.com/repos/thaliproject/Thali_CordovaPlugin/issues/767","repository_url":"https://api.github.com/repos/thaliproject/Thali_CordovaPlugin","labels_url":"https://api.github.com/repos/thaliproject/Thali_CordovaPlugin/issues/767/labels{/name}","comments_url":"https://api.github.com/repos/thaliproject/Thali_CordovaPlugin/issues/767/comments","events_url":"https://api.github.com/repos/thaliproject/Thali_CordovaPlugin/issues/767/events","html_url":"https://github.com/thaliproject/Thali_CordovaPlugin/issues/767","id":166445310,"number":767,"title":"Please test if we can depend on MPCF as a full mux replacement","user":{"login":"yaronyg","id":1480964,"avatar_url":"https://avatars.githubusercontent.com/u/1480964?v=3","gravatar_id":"","url":"https://api.github.com/users/yaronyg","html_url":"https://github.com/yaronyg","followers_url":"https://api.github.com/users/yaronyg/followers","following_url":"https://api.github.com/users/yaronyg/following{/other_user}","gists_url":"https://api.github.com/users/yaronyg/gists{/gist_id}","starred_url":"https://api.github.com/users/yaronyg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yaronyg/subscriptions","organizations_url":"https://api.github.com/users/yaronyg/orgs","repos_url":"https://api.github.com/users/yaronyg/repos","events_url":"https://api.github.com/users/yaronyg/events{/privacy}","received_events_url":"https://api.github.com/users/yaronyg/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/thaliproject/Thali_CordovaPlugin/labels/3%20-%20Working","name":"3 - Working","color":"CCCCCC"}],"state":"open","locked":false,"assignee":{"login":"baydet","id":1755124,"avatar_url":"https://avatars.githubusercontent.com/u/1755124?v=3","gravatar_id":"","url":"https://api.github.com/users/baydet","html_url":"https://github.com/baydet","followers_url":"https://api.github.com/users/baydet/followers","following_url":"https://api.github.com/users/baydet/following{/other_user}","gists_url":"https://api.github.com/users/baydet/gists{/gist_id}","starred_url":"https://api.github.com/users/baydet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/baydet/subscriptions","organizations_url":"https://api.github.com/users/baydet/orgs","repos_url":"https://api.github.com/users/baydet/repos","events_url":"https://api.github.com/users/baydet/events{/privacy}","received_events_url":"https://api.github.com/users/baydet/received_events","type":"User","site_admin":false},"assignees":[{"login":"baydet","id":1755124,"avatar_url":"https://avatars.githubusercontent.com/u/1755124?v=3","gravatar_id":"","url":"https://api.github.com/users/baydet","html_url":"https://github.com/baydet","followers_url":"https://api.github.com/users/baydet/followers","following_url":"https://api.github.com/users/baydet/following{/other_user}","gists_url":"https://api.github.com/users/baydet/gists{/gist_id}","starred_url":"https://api.github.com/users/baydet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/baydet/subscriptions","organizations_url":"https://api.github.com/users/baydet/orgs","repos_url":"https://api.github.com/users/baydet/repos","events_url":"https://api.github.com/users/baydet/events{/privacy}","received_events_url":"https://api.github.com/users/baydet/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/thaliproject/Thali_CordovaPlugin/milestones/7","html_url":"https://github.com/thaliproject/Thali_CordovaPlugin/milestones/New%20Infra","labels_url":"https://api.github.com/repos/thaliproject/Thali_CordovaPlugin/milestones/7/labels","id":1498038,"number":7,"title":"New Infra","description":"This will be the first release of the new infrastructure working end to end.","creator":{"login":"yaronyg","id":1480964,"avatar_url":"https://avatars.githubusercontent.com/u/1480964?v=3","gravatar_id":"","url":"https://api.github.com/users/yaronyg","html_url":"https://github.com/yaronyg","followers_url":"https://api.github.com/users/yaronyg/followers","following_url":"https://api.github.com/users/yaronyg/following{/other_user}","gists_url":"https://api.github.com/users/yaronyg/gists{/gist_id}","starred_url":"https://api.github.com/users/yaronyg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yaronyg/subscriptions","organizations_url":"https://api.github.com/users/yaronyg/orgs","repos_url":"https://api.github.com/users/yaronyg/repos","events_url":"https://api.github.com/users/yaronyg/events{/privacy}","received_events_url":"https://api.github.com/users/yaronyg/received_events","type":"User","site_admin":false},"open_issues":31,"closed_issues":196,"state":"open","created_at":"2016-01-11T19:12:00Z","updated_at":"2016-07-21T00:45:50Z","due_on":"2016-03-31T07:00:00Z","closed_at":null},"comments":1,"created_at":"2016-07-19T21:56:51Z","updated_at":"2016-07-21T14:57:51Z","closed_at":null,"body":"Note: MPCF == Multipeer Connectivity Framework\n\nThe goal of this bug is to determine if we can directly bridge TCP/IP connections from the node layer to the iOS native layer by mapping each TCP/IP connection's individual input/output stream to pairs of 'virtual sockets' in the MPCF layer. \n\nA 'virtual socket' is a pair of output streams going in each direction (e.g. an output stream from A to B and from B to A) that we will map to an individual TCP/IP connection's two streams.\n\nTo test if this goal is possible we need to write a test application that does the following:\n1. Use two phones, each phone MUST run identical test software doing identical things with the exception that it's fine to just anoint one phone as the phone that will invite the other phone to a MCSession\n2. Each phone MUST open N output streams at the MPCF layer to the other phone (where N should default to 20). Over each of these output streams the phone MUST output Y bytes of randomly generated data (Y can start at say 10 MB). Each group of bytes MUST be sent in randomly sized buffers from 1 to 4KB in size. The randomly sized buffers simulate TCP's behavior of sending different buffer sizes. Each phone MUST then wait for the other phone to echo back the data it sent and then the phone MUST confirm that it was echoed back the same data it was sent. When all N connections successfully send and get echoed back Y bytes then the test is a success on that phone.\n3. Each phone MUST listen for incoming streams from the other phone and MUST generate a matching outgoing stream that echoes the bytes received. The echoed bytes MUST be sent in the same buffer sizes they were received. The phone will know it no longer needs to echo data when it has created N echo streams each of which has successfully sent Y bytes of data.\n4. Each phone MUST NOT be connected to a wifi access point while this test is run. Otherwise the test will be bogus because when iOS devices are connected to WiFi they will just use local TCP/IP across the access point to move the data. Therefore both WiFi and Bluetooth MUST be turned on but the WiFi MUST NOT be connected to any access point.\n\nSo the above means we will send N streams * Y bytes * 2 times (once out and once echoed back) * 2 devices worth of bytes.\n\nI will discuss a possible architecture for this test code below but how you implement the code is up to you. The key thing is to go to create a GitHub repo some place and start it with no content and configure it to support reviewable.io. Then submit a PR with the XCode project to it. The code review I will then perform will have the goal of both letting me review how you attacked the problem but also how you deal with multi-threading, code style issues, etc. It's a good dry run to understand how we want code to be written. I'll also want to run the test locally.\n\n## Optional Architecture\n\nYou do not have to implement the code this way. It's just a suggestion and hopefully will clarify goals even if you take a different approach.\n\nNow a fairly simple architecture to implement the previous would be that each phone would have a main thread that would fire off N output workers.\n\nEach output worker would generate a GUID and that GUID would then be entered into a global dictionary indexed by GUID. Each entry would have associated with it a LIFO queue of bytes. The output worker would then open an output stream with that GUID as its name.  The output worker would then start generating Y bytes of data using a random number generator stream outputter and would output those bytes in buffers of size 1 to 4K bytes where the actual buffer size will be randomly picked for each output event (in other words the first buffer might be 10 bytes, the next 1234 bytes, the next 23 bytes, the next 10 bytes, etc.). The various buffer sizes are meant to simulate TCP/IP's random buffer sizes. While the worker is outputting the bytes to the output stream it would simultaneously put those bytes into the LIFO queue in the global dictionary associated with the output worker's GUID. Each worker would exit when it finished transmitting its Y bytes. [Note: You actually don't need a GUID. You could also just pass in a counter created by the main thread to each worker, so long as each worker gets a different counter value then it can use that value as its index and stream name and everything will be fine]\n\nSimultaneously there would be a listener for input streams. Whenever an input stream is received an input worker would be assigned to it. The first thing the input worker would do is see if the stream's name is in the global dictionary of GUIDS mentioned above. \n\nIf it is not then the input worker would immediately open an output stream to the other device with the same name as the input stream. The input worker would then take any buffers of bytes received from the input stream and immediately copy them using the same buffer size to the identically named output stream. The input worker would count how many bytes it has sent and when it reaches Y bytes it will know it is done and can exit.\n\nIf the name of the input stream is in the global dictionary of GUIDs then this means that the stream is an echo back to the local device of bytes it has sent to the remote device. In that case the input worker needs to look up the LIFO in the global dictionary for that GUID and start matching the incoming bytes it is receiving against the bytes in the LIFO. If there are any mis-matches (e.g. bytes received on the input stream don't match the bytes in the LIFO) then an exception MUST be thrown and the test MUST fail. If all Y bytes are received and matched then the input worker will exit.\n\nThe main thread knows the test is over when the N output workers successfully exit and when 2N input workers (N of which are just echo'ing the other devices bytes and N of which are confirming echos sent over from the other device) successfully exit.\n\n<!---\n@huboard:{\"order\":743.0743018575,\"milestone_order\":1.3551172038864919e-20,\"custom_state\":\"\"}\n-->\n"},"comment":{"url":"https://api.github.com/repos/thaliproject/Thali_CordovaPlugin/issues/comments/234280370","html_url":"https://github.com/thaliproject/Thali_CordovaPlugin/issues/767#issuecomment-234280370","issue_url":"https://api.github.com/repos/thaliproject/Thali_CordovaPlugin/issues/767","id":234280370,"user":{"login":"yaronyg","id":1480964,"avatar_url":"https://avatars.githubusercontent.com/u/1480964?v=3","gravatar_id":"","url":"https://api.github.com/users/yaronyg","html_url":"https://github.com/yaronyg","followers_url":"https://api.github.com/users/yaronyg/followers","following_url":"https://api.github.com/users/yaronyg/following{/other_user}","gists_url":"https://api.github.com/users/yaronyg/gists{/gist_id}","starred_url":"https://api.github.com/users/yaronyg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yaronyg/subscriptions","organizations_url":"https://api.github.com/users/yaronyg/orgs","repos_url":"https://api.github.com/users/yaronyg/repos","events_url":"https://api.github.com/users/yaronyg/events{/privacy}","received_events_url":"https://api.github.com/users/yaronyg/received_events","type":"User","site_admin":false},"created_at":"2016-07-21T14:57:50Z","updated_at":"2016-07-21T14:57:50Z","body":"The current issue is that we aren't getting any data back or at least it hangs for a long time before showing up. Also it turns out that the current test isn't symmetric, the initiator is the only one who starts sending data and the other device just responds. We need the test to be symmetric. So Alex will fix the test and also test with N = 1 to see if data flows when there is just one connection as Toby found of if the problem is something in his code. Alex will also look at Toby's old code to see how he handled things and we'll start a thread with Toby to see if he has any advice."}}
{"actor":{"display_login":"yaronyg"}}