/help-tcp

Primary LanguageJavaScript

Help.com backend project by Jhorlin De Armas

Acceptance Criteria

Your program should demonstrate the following as well as demonstrate good coding practices.

  • Connect and log into the system.
  • Handle heartbeats appropriately and depict the reconnection logic if you do not receive a heartbeat.
  • Handle input from STDIN so your user can manually send JSON data to the server process.
  • Receive responses only for requests your client sends.
  • Verify and validate input to be sent, and also handle errors sent by the server.
  • If the random number sent back from the result of the "time" call is greater than 30, it should print out a message saying so.
  • Provide a way to send both the "count" and "time" calls to the worker process and show the results in a nicely formatted way.

Usage

To test run $ npm test To run use $ help-tcp <username>

###My solution. I decided to solve this problem using FRP specifically rxjs. I chose this patter because I felt it fit this use case well and allwed me to play with FRP, which I don't get to do as much as I would like. The basic idea is to create a stream from a tcp connection. By default sources are replayed so I needed to make this a sharable stream, this means that any subscriber will get notified of what is happening live and not get a replay. This also allowed me to keep track of subscribers. In this example the subscribers were the heartbeat and any active request. When there were no more subscribers I cold close the connection. The tcp takes in two arguments, a function to create a stream (this will happen on the first subscription only) and a function called when there are no more subscriptions. Create destroy. This works really well because we can now create a heart beat subscription based on our tcp source. Now that we have a stream we can filter out any matches for hearbeat and set a timeout. We can also conditionally retry for a TimeoutError. The retry logic works because if there is an error, the heartbeat subscription is unsubscribed. Once there are no more subscriptions we will remove the client then immediately create a new one. Also since we are handling our async through streams we can do the same for our commands. We create a source from an EventEmmiter and when we create a client we subscribe to the event source and pump messages into that client.

###Thoughts I chose to set a timeout on the command source/observable so that there are no lingering requests since the cli waits for a selecton before you can chose a different one. This limitation is just for cli simplicity. Since each command is it own subscription based on a the tcpSource each subscription monitors the same tcp source but the filter is not shared. This solution can multiplex many commands from one tcp connection and each command will have its own error, depending on how far down stream that error is. Parsing errors will only effect that command while tcp errors will propagate to all commands. Also each command can complete in any order irrelevant of request order.