Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mcfilib/dropcure
Toy project demonstrating WebSockets in Haskell
https://github.com/mcfilib/dropcure
haskell websockets
Last synced: 23 days ago
JSON representation
Toy project demonstrating WebSockets in Haskell
- Host: GitHub
- URL: https://github.com/mcfilib/dropcure
- Owner: mcfilib
- Created: 2017-07-23T09:34:26.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-01-24T09:37:17.000Z (about 6 years ago)
- Last Synced: 2024-11-15T04:42:03.888Z (3 months ago)
- Topics: haskell, websockets
- Language: Haskell
- Size: 68.4 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# dropcure
`dropcure` was a take home assignment I did as part of a job interview. It consists of two services and
one library.- `producer` - publishes messages received on websockets to a message queue.
- `consumer` - broadbasts messages from the message queue to clients connected via websockets.
- `common` - shared code for both services.## Overview
Both `producer` and `consumer` follow a similar pattern in that each implements
a client and a server as a subcommand.### producer
#### Server
The `producer` server operates as follows:
- Wait for RabbitMQ service to become available.
- Connect to RabbitMQ server and create queue and channel if it doesn't exist.
- Disconnect from RabbitMQ.
- On new websocket connection:
- Connect to RabbitMQ.
- Send handshake message.
- Repeatedly publish any message to RabbitMQ.#### Client
The `producer` client is intended to be used for debugging purposes and operates
as follows:- Connect to server.
- Receive handshake.
- Every `n` seconds emit a static message (`"beep"`).### consumer
#### Sever
The `consumer` server operates as follows:
- Initialise an empty mapping between unique identifiers and websocket.
- Wait for RabbitMQ service to become available.
- Connect to RabbitMQ server and create queue and channel if it doesn't exist.
- Subscribe to the queue.
- On new websocket connection:
- Create unique identifier.
- Add connection to mapping for given identifier.
- On websocket disconnection:
- Remove connection from mapping.
- On new message in the queue:
- Enumerate all connections in mapping and emit message via websockets.#### Client
The `consumer` client is intended to be used for debugging purposes and operates
as follows:- Connect to server.
- Receive handshake.
- On new message emitted by the server:
- Print it to `stdout`.## Future Enhancements
### Functionality
- [ ] Handle situation when RabbitMQ goes down.
### Testing
- [ ] Add more tests.
- [ ] Add mocks to test `IO` without doing `IO` as outlined in [this blog post](https://lexi-lambda.github.io/blog/2017/06/29/unit-testing-effectful-haskell-with-monad-mock/).### Operations
- [ ] Add Docker build image so that it doesn't rely on the host OS being the same as the target.
- [ ] Shrink Docker image e.g. use Alpine with `glibc` to keep the image sizes down.
- [ ] Re-enable layer caching.## Usage
The instructions below assume that you are
running [Ubuntu](https://www.ubuntu.com/),
have [Stack](https://docs.haskellstack.org/en/stable/README/) installed and have
the [Docker](https://www.docker.com/) daemon running.```
$ make up # start necessary services
$ WEBSOCKET_PORT=8001 consumer client # run the consumer client
$ WEBSOCKET_PORT=8000 producer client # run the producer client
```### Dependencies
- `docker`
- `stack`
- `ubuntu`## Development
### Tasks
```
% make
build Build producer and consumer Docker containers
clean Clean up build artefacts
help Print available tasks
install Compile producer and consumer
up Start services
```