-
Notifications
You must be signed in to change notification settings - Fork 2
/
README.lhs
182 lines (135 loc) · 5.33 KB
/
README.lhs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# faktory\_worker\_haskell
[![Hackage](https://img.shields.io/hackage/v/faktory.svg?style=flat)](https://hackage.haskell.org/package/faktory)
[![Stackage Nightly](http://stackage.org/package/faktory/badge/nightly)](http://stackage.org/nightly/package/faktory)
[![Stackage LTS](http://stackage.org/package/faktory/badge/lts)](http://stackage.org/lts/package/faktory)
[![CI](https://github.com/freckle/faktory_worker_haskell/actions/workflows/ci.yml/badge.svg)](https://github.com/freckle/faktory_worker_haskell/actions/workflows/ci.yml)
Haskell client and worker process for the Faktory background job server.
Architecture overview from [Ruby client README](https://github.com/contribsys/faktory_worker_ruby#readme):
```
+--------------------+
| |
| Faktory |
| Server |
+---------->>>>| +>>>>--------+
| | | |
| | | |
| +--------------------+ |
+-----------------+ +-------------------+
| | | |
| Client | | Worker |
| pushes | | pulls |
| jobs | | jobs |
| | | |
| | | |
+-----------------+ +-------------------+
```
- Client - an API any process can use to push jobs to the Faktory server.
- Worker - a process that pulls jobs from Faktory and executes them.
- Server - the Faktory daemon which stores background jobs in queues to be
processed by Workers.
This package contains only the client and worker parts. The server part is
[here](https://github.com/contribsys/faktory/)
## Installation
- Hackage: http://hackage.haskell.org/package/faktory
- Stackage: *Coming soon*
## Faktory Documentation
See the [wiki](//github.com/contribsys/faktory/wiki) for more
details.
## Usage
<!--
```haskell
import Data.Aeson
import Prelude
import Faktory.Producer
import Faktory.Job
import Faktory.Worker
import GHC.Generics
import Text.Markdown.Unlit ()
{- Don't actually run anything -}
main :: IO ()
main = if True then pure () else (workerMain >> producerMain)
workerMain :: IO ()
producerMain :: IO ()
```
-->
### Job
Any value can be a "Job" that is pushed and pulled to and from Faktory via its
`ToJSON` and `FromJSON` instances:
```haskell
newtype MyJob = MyJob
{ myJobMessage :: String
}
deriving stock Generic
deriving anyclass (ToJSON, FromJSON)
```
### Worker
```haskell
workerMain = runWorkerEnv $ \job -> do
-- Process your Job here
putStrLn $ jobJid job
putStrLn $ myJobMessage $ jobArg job
-- If any exception is thrown, the job will be marked as Failed in Faktory
-- and retried. Note: you will not otherwise hear about any such exceptions,
-- unless you catch-and-rethrow them yourself.
```
### Producer
`Producer` wraps `Client` for push-only usage.
```haskell
producerMain = do
producer <- newProducerEnv
jobId <- perform mempty producer $ MyJob "Hello world"
print jobId
closeProducer producer
```
### Configuration
When using `envSettings`, the following variables will be used:
- `FAKTORY_PROVIDER`: the name of another environment variable where the
connection string can be found. Defaults to `FAKTORY_URL`.
- `FAKTORY_URL` (or whatever you named in `FAKTORY_PROVIDER`): connection string
to the Faktory server. Format is
`tcp(+tls)://(:password@)host:port(/namespace)`. Defaults to
`tcp://localhost:4719`. `namespace` is prependend to queue names on job
submission and worker consumption.
When using `envWorkerSettings`, the following variables are also used:
- `FAKTORY_QUEUE`: the name of the queue to consume from. Default is "default".
- `FAKTORY_WORKER_ID`: the Id to use for this Worker. Default is to assign a
random one.
## Examples
See the [examples](./examples). To run them:
1. Run a local Faktory server
```console
docker run --rm \
--publish 7419:7419 \
--publish 7420:7420 \
contribsys/faktory
```
1. Run the consumer example
```console
% stack exec faktory-example-consumer
Starting consumer loop
```
(Assumes you've built the project.)
1. Submit a Job through the producer example
```console
% stack exec faktory-example-producer hello world
Pushed job: "ljcjlbexbgun"
```
*NOTE*: if you submit "BOOM" as a Job, the processing loop will raise an
exception, so you can see how a Failed Job looks in Faktory.
1. See that your Job was processed back in the consumer
```console
% stack exec faktory-example-consumer
Starting consumer loop
hello world
```
## Development & Tests
```console
stack build --dependencies-only --test --no-run-tests
stack build --pedantic --test --no-run-tests
stack build --pedantic --test
```
- `FactorySpec` requires a local Faktory server is running, and it will flush
all Jobs from this server as part of running the tests.
- The tests for `BATCH` require testing against an Enterprise Faktory image
---
[CHANGELOG](./CHANGELOG.md) | [LICENSE](./LICENSE)