EventServer is a socket server which reads events from an event source and forwards them to the user clients when appropriate.
Check the section Implementation Details below for more details.
Make sure you have a working Go environment.
- Golang 1.8 or later
Steps to install and run the server
- Clone the repository into your GOPATH
- Go to the project directory:
./config/config.jsonfile to configure the event source and user client ports as you want.
- Run the event server:
- The event server will show give output like below:
INFO: 2017/12/17 15:00:46 eventserver.go:508: Loaded the event server config INFO: 2017/12/17 15:00:46 eventserver.go:83: Listening for event source on port: 9090 INFO: 2017/12/17 15:00:46 eventserver.go:91: Listening for user clients on port: 9099 INFO: 2017/12/17 15:00:46 eventserver.go:515: Started the event server
The server is now running and listening on ports mentioned
Note: If you don't have
make, you can build the binary using:
$ go build .
And then run the binary using:
To run tests for the entire package:
$ make test
To run the tests with coverage:
$ make test-cover
To run the benchmark tests for the package:
$ make test-bench
To format the code during development:
$ make fmt
By default, the above command is of dry nature. It only shows the changes that gofmt tool suggests.
To actually make the changes, you need to run:
$ make fmt-wet
golint on the source code:
$ make lint
Quick test program
To test the event server with a test program that comes with this repository, run the following command in another terminal:
$ make harness
This script will initialize a test program which starts sending events.
Note: The test program uses port 9090 for event source and 9099 for user clients by default. If you want to use different ports, you can set the following environment variables: eventListenerPort and clientListenerPort.
Running in Production
To run EventServer in production, you can install the versioned binary file
and run it with the corresponding
Event Server accepts the following command line argument(s):
-config string config file to load (default "./config/config.json")
To run the compiled binary in production with custom config file:
$ ./go-eventserver -config "/path/to/config/file"
The configuration file in production can be served using some configuration management tool like Puppet or Chef.
You can configure the following parameters of the server by specifying them
- eventListenerPort - The port used by the event source.
- clientListenerPort - The port used to register clients.
- event source: It will send a stream of events which may or may not require clients to be notified.
- user clients: Each one representing a specific user, these wait for notifications for events which would be relevant to the user they represent.
There are five possible events. The table below describe payloads sent by the event source and what they represent:
|Payload||Sequence #||Type||From User Id||To User Id|
instructions.md to read more about these event types.
Events can come out of order, but clients will always receive the events in the right order of sequence number.
Scope of Improvement
- Logging: Logging can be improved. Right now, only the info logs are being sent to stdout and the error logs are being sent to stderr. The current implementation uses the built-in "log" package. We can use some more mature logging module which can support the levelled logging to support different log levels like - debug, info, warn, error, fatal.
- Monitoring: The current implementation does not have any kind of monitoring around the system. We should have some monitoring to measure how many events we are serving, what kind of clients are connecting and if everything is going alright with our server. We can use go-metrics package. We can keep these monitoring metrics in graphite and then use some tools like Bosun to enable alerts in undesirable situations.
- Sequence persistence: We can implement the offset management similar to
how Kafka handles it in order to solve the following problems:
- Make the server recover from the sequence number where it stopped earlier. For example - in case something goes wrong with the server and it stops in the middle, what happens with the events that it already had received?
- Support the scenario when an event source ends the message streams and want to start sending events again? Two possibilities - do we start processing from the sequence number where we left or do we start from 1?