Skip to content

Design Decisions

Ian Carroll edited this page Oct 30, 2017 · 1 revision

Basics:

  • Clean Code and SOLID principles
  • Imperative Shell / Functional Core Pattern
  • Employing an Observer Pattern using Reactive Programming via JavaRX to handle concurrent requests
  • Using dependency injection to construct the server at start-up via a Factory
  • Using a config file to handle routing

High-level Flow:

  1. The Server Starts.
  2. The Client sends a byte[] request to the Server.
  3. The Server sends an appropriate byte[] response back to the Client.

More specific Flow:

  1. Main Function Calls a Factory to construct the server, then calls Server.start
    • Factory takes in any command-line args and constructs the server accordingly
    • The Config file with routing info is injected at this stage.
  2. The Server Socket Class spins up with a Client Socket dependency injected.
    • The Server socket employs reactive programming to never develop a stack of waiting requests. Concurrency is implemented at this stage.
    • When A request event is triggered, the server socket copies a new stream to handle spinning up a client socket to accept the request. This moves the bottleneck from the moment of client socket instantiation to the hardware running the server.
  3. The request is converted from a byte[] to a String
  4. The String is parsed and the parts are instantiated as a Request Object.
  5. The Request Object is sent to the Controller, which uses the Routes config to match the request with an appropriate Response Generator.
  6. The Response Generator returns a response object to the Controller.
  7. The Controller sends the response object to be de-parsed back into a string.
  8. The string is converted into a byte array
  9. The Client Socket class sends that byte array as a response to the client's request.

Clone this wiki locally