busybee 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +71 -7
  3. data/README.md +70 -42
  4. data/docs/client/quick_start.md +279 -0
  5. data/docs/client.md +825 -0
  6. data/docs/configuration.md +550 -0
  7. data/docs/grpc.md +50 -25
  8. data/docs/testing.md +118 -28
  9. data/docs/workers.md +982 -0
  10. data/exe/busybee +6 -0
  11. data/lib/busybee/cli.rb +173 -0
  12. data/lib/busybee/client/error_handling.rb +37 -0
  13. data/lib/busybee/client/job_operations.rb +236 -0
  14. data/lib/busybee/client/message_operations.rb +84 -0
  15. data/lib/busybee/client/process_operations.rb +108 -0
  16. data/lib/busybee/client/variable_operations.rb +64 -0
  17. data/lib/busybee/client.rb +87 -0
  18. data/lib/busybee/configure.rb +290 -0
  19. data/lib/busybee/credentials/camunda_cloud.rb +58 -0
  20. data/lib/busybee/credentials/insecure.rb +24 -0
  21. data/lib/busybee/credentials/oauth.rb +157 -0
  22. data/lib/busybee/credentials/tls.rb +43 -0
  23. data/lib/busybee/credentials.rb +200 -0
  24. data/lib/busybee/defaults.rb +20 -0
  25. data/lib/busybee/error.rb +50 -0
  26. data/lib/busybee/grpc/error.rb +60 -0
  27. data/lib/busybee/grpc.rb +2 -2
  28. data/lib/busybee/job.rb +219 -0
  29. data/lib/busybee/job_stream.rb +85 -0
  30. data/lib/busybee/logging.rb +61 -0
  31. data/lib/busybee/railtie.rb +113 -0
  32. data/lib/busybee/runner/hybrid.rb +64 -0
  33. data/lib/busybee/runner/multi.rb +101 -0
  34. data/lib/busybee/runner/polling.rb +54 -0
  35. data/lib/busybee/runner/streaming.rb +159 -0
  36. data/lib/busybee/runner.rb +97 -0
  37. data/lib/busybee/runtime_config.rb +184 -0
  38. data/lib/busybee/serialization.rb +100 -0
  39. data/lib/busybee/testing/activated_job.rb +33 -8
  40. data/lib/busybee/testing/helpers/execution.rb +139 -0
  41. data/lib/busybee/testing/helpers/support.rb +78 -0
  42. data/lib/busybee/testing/helpers.rb +56 -66
  43. data/lib/busybee/testing/matchers/complete_job.rb +55 -0
  44. data/lib/busybee/testing/matchers/fail_job.rb +75 -0
  45. data/lib/busybee/testing/matchers/have_activated.rb +1 -1
  46. data/lib/busybee/testing/matchers/have_available_jobs.rb +44 -0
  47. data/lib/busybee/testing/matchers/throw_bpmn_error_on.rb +72 -0
  48. data/lib/busybee/testing.rb +5 -33
  49. data/lib/busybee/version.rb +1 -1
  50. data/lib/busybee/worker/configuration.rb +287 -0
  51. data/lib/busybee/worker/dsl.rb +187 -0
  52. data/lib/busybee/worker/shutdown.rb +27 -0
  53. data/lib/busybee/worker.rb +130 -0
  54. data/lib/busybee.rb +134 -2
  55. metadata +80 -3
@@ -0,0 +1,550 @@
1
+ # Gem Configuration
2
+
3
+ Busybee provides a flexible configuration system that adapts to different environments — from local development with Docker to production deployments with Camunda Cloud. Configuration can be set through Ruby code, environment variables, or Rails configuration, with sensible defaults that work out of the box.
4
+
5
+ This document covers gem-level settings: connection, credentials, logging, and operation defaults. For worker runtime configuration (CLI flags, YAML files, worker modes, and the config precedence chain), see [Workers: Running Workers](workers.md#running-workers).
6
+
7
+ ## Quick Start
8
+
9
+ Most Busybee configuration is optional. The simplest setup requires no configuration at all for local development:
10
+
11
+ ```ruby
12
+ # Connects to localhost:26500 with insecure credentials
13
+ client = Busybee::Client.new
14
+ ```
15
+
16
+ For Camunda Cloud, set environment variables and Busybee auto-detects the credential type:
17
+
18
+ ```bash
19
+ export CAMUNDA_CLIENT_ID="your-client-id"
20
+ export CAMUNDA_CLIENT_SECRET="your-client-secret"
21
+ export CAMUNDA_CLUSTER_ID="your-cluster-id"
22
+ export CAMUNDA_CLUSTER_REGION="bru-2"
23
+ ```
24
+
25
+ ```ruby
26
+ # Automatically uses Camunda Cloud credentials
27
+ client = Busybee::Client.new
28
+ ```
29
+
30
+ For more control, use the configure block:
31
+
32
+ ```ruby
33
+ Busybee.configure do |config|
34
+ config.cluster_address = "zeebe.example.com:443"
35
+ config.credential_type = :oauth
36
+ config.logger = Logger.new($stdout)
37
+ config.grpc_retry_enabled = true
38
+ end
39
+ ```
40
+
41
+ ## Configuration Methods
42
+
43
+ There are three ways to configure Busybee, which can be mixed as needed.
44
+
45
+ ### Configure Block
46
+
47
+ The `Busybee.configure` block is the recommended approach for application setup:
48
+
49
+ ```ruby
50
+ # config/initializers/busybee.rb (or anywhere during app boot)
51
+ Busybee.configure do |config|
52
+ config.cluster_address = ENV.fetch("ZEEBE_ADDRESS")
53
+ config.credential_type = :oauth
54
+ config.logger = Rails.logger
55
+ config.log_format = :json
56
+ config.grpc_retry_enabled = true
57
+ end
58
+ ```
59
+
60
+ ### Direct Assignment
61
+
62
+ Configuration attributes can also be set directly:
63
+
64
+ ```ruby
65
+ Busybee.cluster_address = "zeebe:26500"
66
+ Busybee.logger = Logger.new($stdout)
67
+ ```
68
+
69
+ ### Environment Variables
70
+
71
+ Several configuration options fall back to environment variables when not explicitly set:
72
+
73
+ | Attribute | Environment Variable | Notes |
74
+ |-----------|---------------------|-------|
75
+ | `cluster_address` | `CLUSTER_ADDRESS` | Falls back to `localhost:26500` |
76
+ | `credential_type` | `BUSYBEE_CREDENTIAL_TYPE` | One of: insecure, tls, oauth, camunda_cloud |
77
+ | `worker_name` | `BUSYBEE_WORKER_NAME` | Falls back to hostname |
78
+
79
+ Credential-specific environment variables are documented in [Client: Environment Variables](client.md#environment-variables).
80
+
81
+ ## Configuration Reference
82
+
83
+ ### Connection Settings
84
+
85
+ #### `cluster_address`
86
+
87
+ The Zeebe gateway address in `host:port` format.
88
+
89
+ | | |
90
+ |--|--|
91
+ | **Type** | String |
92
+ | **Default** | `"localhost:26500"` |
93
+ | **Env var** | `CLUSTER_ADDRESS` |
94
+
95
+ ```ruby
96
+ Busybee.cluster_address = "zeebe.example.com:443"
97
+ ```
98
+
99
+ #### `credential_type`
100
+
101
+ Explicitly selects the credential type. When set, Busybee uses this type to build Credentials rather than auto-detecting from the provided parameters.
102
+
103
+ | | |
104
+ |--|--|
105
+ | **Type** | Symbol |
106
+ | **Default** | `nil` (auto-detect) |
107
+ | **Env var** | `BUSYBEE_CREDENTIAL_TYPE` |
108
+ | **Valid values** | `:insecure`, `:tls`, `:oauth`, `:camunda_cloud` |
109
+
110
+ ```ruby
111
+ Busybee.credential_type = :oauth
112
+ ```
113
+
114
+ See [Client: Providing Credentials](client.md#providing-credentials) for detailed credential configuration.
115
+
116
+ #### `credentials`
117
+
118
+ An explicit `Busybee::Credentials` object. When set, this is used directly rather than building credentials from parameters.
119
+
120
+ | | |
121
+ |--|--|
122
+ | **Type** | `Busybee::Credentials` |
123
+ | **Default** | `nil` |
124
+
125
+ ```ruby
126
+ Busybee.credentials = Busybee::Credentials::TLS.new(
127
+ cluster_address: "zeebe.example.com:443",
128
+ certificate_file: "/path/to/ca.crt"
129
+ )
130
+ ```
131
+
132
+ ### Logging
133
+
134
+ #### `logger`
135
+
136
+ The logger instance for Busybee messages. When `nil`, logging is disabled.
137
+
138
+ | | |
139
+ |--|--|
140
+ | **Type** | Logger-compatible object |
141
+ | **Default** | `nil` (Rails: `Rails.logger`) |
142
+
143
+ ```ruby
144
+ Busybee.logger = Logger.new($stdout)
145
+ ```
146
+
147
+ #### `log_format`
148
+
149
+ Controls log message formatting.
150
+
151
+ | | |
152
+ |--|--|
153
+ | **Type** | Symbol |
154
+ | **Default** | `:text` |
155
+ | **Valid values** | `:text`, `:json` |
156
+
157
+ **Text format** (default):
158
+ ```
159
+ [busybee] Retrying after GRPC error (attempt: 1, error: "Unavailable")
160
+ ```
161
+
162
+ **JSON format**:
163
+ ```json
164
+ {"message":"[busybee] Retrying after GRPC error","level":"warn","attempt":1,"error":"Unavailable"}
165
+ ```
166
+
167
+ ```ruby
168
+ Busybee.log_format = :json
169
+ ```
170
+
171
+ ### GRPC Retry
172
+
173
+ Busybee can automatically retry failed GRPC calls for transient errors. Retry is disabled by default.
174
+
175
+ #### `grpc_retry_enabled`
176
+
177
+ Whether to retry failed GRPC calls.
178
+
179
+ | | |
180
+ |--|--|
181
+ | **Type** | Boolean |
182
+ | **Default** | `false` |
183
+
184
+ ```ruby
185
+ Busybee.grpc_retry_enabled = true
186
+ ```
187
+
188
+ #### `grpc_retry_delay_ms`
189
+
190
+ Delay in milliseconds before retrying a failed GRPC call.
191
+
192
+ | | |
193
+ |--|--|
194
+ | **Type** | Integer |
195
+ | **Default** | `500` |
196
+
197
+ ```ruby
198
+ Busybee.grpc_retry_delay_ms = 1000
199
+ ```
200
+
201
+ #### `grpc_retry_errors`
202
+
203
+ GRPC error classes that trigger a retry.
204
+
205
+ | | |
206
+ |--|--|
207
+ | **Type** | Array of GRPC error classes |
208
+ | **Default** | `[GRPC::Unavailable, GRPC::DeadlineExceeded, GRPC::ResourceExhausted]` |
209
+
210
+ ```ruby
211
+ # Only retry on Unavailable
212
+ Busybee.grpc_retry_errors = [GRPC::Unavailable]
213
+ ```
214
+
215
+ ### Operation Defaults
216
+
217
+ #### `default_message_ttl`
218
+
219
+ Default time-to-live for published messages, in milliseconds. Individual `publish_message` calls can override this.
220
+
221
+ | | |
222
+ |--|--|
223
+ | **Type** | Integer (milliseconds) |
224
+ | **Default** | `10_000` (10 seconds) |
225
+
226
+ ```ruby
227
+ Busybee.default_message_ttl = 60_000 # 1 minute
228
+ ```
229
+
230
+ #### `default_fail_job_backoff`
231
+
232
+ Default backoff time when failing a job, in milliseconds. Individual `fail_job` calls can override this.
233
+
234
+ | | |
235
+ |--|--|
236
+ | **Type** | Integer (milliseconds) |
237
+ | **Default** | `5_000` (5 seconds) |
238
+
239
+ ```ruby
240
+ Busybee.default_fail_job_backoff = 10_000 # 10 seconds
241
+ ```
242
+
243
+ #### `default_job_request_timeout`
244
+
245
+ Default timeout for job activation requests, in milliseconds. This controls how long the Zeebe gateway waits for jobs to become available before returning an empty response. Individual `with_each_job` and `activate_job` calls can override this.
246
+
247
+ | | |
248
+ |--|--|
249
+ | **Type** | Integer (milliseconds) or ActiveSupport::Duration |
250
+ | **Default** | `60_000` (60 seconds) |
251
+
252
+ ```ruby
253
+ Busybee.default_job_request_timeout = 30_000 # 30 seconds
254
+ Busybee.default_job_request_timeout = 30.seconds
255
+ ```
256
+
257
+ #### `default_job_lock_timeout`
258
+
259
+ Default lock timeout for activated jobs, in milliseconds. This controls how long a worker has to process a job before the lock expires and the job becomes available to other workers. Individual `with_each_job` and `open_job_stream` calls can override this.
260
+
261
+ | | |
262
+ |--|--|
263
+ | **Type** | Integer (milliseconds) or ActiveSupport::Duration |
264
+ | **Default** | `60_000` (60 seconds) |
265
+
266
+ ```ruby
267
+ Busybee.default_job_lock_timeout = 120_000 # 2 minutes
268
+ Busybee.default_job_lock_timeout = 2.minutes
269
+ ```
270
+
271
+ #### `worker_name`
272
+
273
+ Identifier for this worker instance, used in job activation. Useful for debugging which worker processed a job.
274
+
275
+ | | |
276
+ |--|--|
277
+ | **Type** | String |
278
+ | **Default** | Hostname (via `Socket.gethostname`) |
279
+ | **Env var** | `BUSYBEE_WORKER_NAME` |
280
+
281
+ ```ruby
282
+ Busybee.worker_name = "worker-#{Process.pid}"
283
+ ```
284
+
285
+ ## Rails Integration
286
+
287
+ When Rails is detected, Busybee automatically loads a Railtie that:
288
+
289
+ 1. Sets `Busybee.logger` to `Rails.logger`
290
+ 2. Reads configuration from `config.x.busybee.*`
291
+
292
+ ### Basic Rails Setup
293
+
294
+ ```ruby
295
+ # config/application.rb
296
+ module MyApp
297
+ class Application < Rails::Application
298
+ config.x.busybee.cluster_address = "zeebe.example.com:443"
299
+ config.x.busybee.credential_type = :oauth
300
+ end
301
+ end
302
+ ```
303
+
304
+ ### Environment-Specific Configuration
305
+
306
+ ```ruby
307
+ # config/environments/development.rb
308
+ Rails.application.configure do
309
+ config.x.busybee.cluster_address = "localhost:26500"
310
+ # credential_type not set - defaults to :insecure for local development
311
+ end
312
+
313
+ # config/environments/production.rb
314
+ Rails.application.configure do
315
+ config.x.busybee.cluster_address = ENV.fetch("ZEEBE_CLUSTER_ADDRESS")
316
+ config.x.busybee.credential_type = :oauth
317
+ config.x.busybee.grpc_retry_enabled = true
318
+ end
319
+ ```
320
+
321
+ ### Separate Initializer
322
+
323
+ For more complex configuration, use an initializer:
324
+
325
+ ```ruby
326
+ # config/initializers/busybee.rb
327
+ Rails.application.config.x.busybee.tap do |busybee|
328
+ busybee.cluster_address = ENV.fetch("ZEEBE_CLUSTER_ADDRESS", "localhost:26500")
329
+ busybee.credential_type = Rails.env.production? ? :camunda_cloud : :insecure
330
+ busybee.grpc_retry_enabled = Rails.env.production?
331
+ busybee.default_message_ttl = 30_000
332
+ end
333
+ ```
334
+
335
+ ### Available Railtie Settings
336
+
337
+ All module-level configuration attributes can be set via `config.x.busybee.*`:
338
+
339
+ | Rails Config | Maps To |
340
+ |--------------|---------|
341
+ | `config.x.busybee.logger` | `Busybee.logger` |
342
+ | `config.x.busybee.log_format` | `Busybee.log_format` |
343
+ | `config.x.busybee.cluster_address` | `Busybee.cluster_address` |
344
+ | `config.x.busybee.credential_type` | `Busybee.credential_type` |
345
+ | `config.x.busybee.credentials` | `Busybee.credentials` |
346
+ | `config.x.busybee.worker_name` | `Busybee.worker_name` |
347
+ | `config.x.busybee.grpc_retry_enabled` | `Busybee.grpc_retry_enabled` |
348
+ | `config.x.busybee.grpc_retry_delay_ms` | `Busybee.grpc_retry_delay_ms` |
349
+ | `config.x.busybee.grpc_retry_errors` | `Busybee.grpc_retry_errors` |
350
+ | `config.x.busybee.default_message_ttl` | `Busybee.default_message_ttl` |
351
+ | `config.x.busybee.default_fail_job_backoff` | `Busybee.default_fail_job_backoff` |
352
+ | `config.x.busybee.default_job_request_timeout` | `Busybee.default_job_request_timeout` |
353
+ | `config.x.busybee.default_job_lock_timeout` | `Busybee.default_job_lock_timeout` |
354
+ | `config.x.busybee.default_worker_mode` | `Busybee.default_worker_mode` |
355
+ | `config.x.busybee.default_max_jobs` | `Busybee.default_max_jobs` |
356
+ | `config.x.busybee.default_buffer` | `Busybee.default_buffer` |
357
+ | `config.x.busybee.default_buffer_throttle` | `Busybee.default_buffer_throttle` |
358
+ | `config.x.busybee.default_backpressure_delay` | `Busybee.default_backpressure_delay` |
359
+ | `config.x.busybee.default_input_required` | `Busybee.default_input_required` |
360
+ | `config.x.busybee.default_output_required` | `Busybee.default_output_required` |
361
+ | `config.x.busybee.shutdown_on_errors` | `Busybee.shutdown_on_errors` |
362
+
363
+ **Credential configuration:**
364
+
365
+ In addition to `credential_type` and `credentials`, you can configure credential parameters directly. The Railtie builds a credentials object automatically when parameters are provided:
366
+
367
+ | Rails Config | Used By | Description |
368
+ |--------------|---------|-------------|
369
+ | `config.x.busybee.client_id` | OAuth, Camunda Cloud | OAuth client ID |
370
+ | `config.x.busybee.client_secret` | OAuth, Camunda Cloud | OAuth client secret |
371
+ | `config.x.busybee.cluster_id` | Camunda Cloud | Camunda Cloud cluster UUID |
372
+ | `config.x.busybee.region` | Camunda Cloud | Camunda Cloud region (e.g., `"bru-2"`) |
373
+ | `config.x.busybee.token_url` | OAuth | OAuth token endpoint URL |
374
+ | `config.x.busybee.audience` | OAuth | OAuth audience |
375
+ | `config.x.busybee.scope` | OAuth, Camunda Cloud | OAuth scope (optional) |
376
+ | `config.x.busybee.certificate_file` | TLS, OAuth | Path to CA certificate file |
377
+
378
+ Three approaches to credential configuration:
379
+
380
+ ```ruby
381
+ # config/environments/production.rb
382
+ Rails.application.configure do
383
+ # Option 1: Minimal - set credential_type, use ENV vars for secrets
384
+ # (CAMUNDA_CLIENT_ID, CAMUNDA_CLIENT_SECRET, etc.)
385
+ config.x.busybee.credential_type = :camunda_cloud
386
+
387
+ # Option 2: Full config - use Rails encrypted credentials
388
+ config.x.busybee.credential_type = :camunda_cloud
389
+ config.x.busybee.client_id = Rails.application.credentials.zeebe[:client_id]
390
+ config.x.busybee.client_secret = Rails.application.credentials.zeebe[:client_secret]
391
+ config.x.busybee.cluster_id = Rails.application.credentials.zeebe[:cluster_id]
392
+ config.x.busybee.region = "bru-2"
393
+
394
+ # Option 3: Explicit credentials object
395
+ config.x.busybee.credentials = Busybee::Credentials::OAuth.new(
396
+ cluster_address: "zeebe.example.com:443",
397
+ token_url: "https://auth.example.com/oauth/token",
398
+ client_id: Rails.application.credentials.zeebe[:client_id],
399
+ client_secret: Rails.application.credentials.zeebe[:client_secret],
400
+ audience: "zeebe-api"
401
+ )
402
+ end
403
+ ```
404
+
405
+ When both `credential_type` and credential parameters are provided, Busybee builds the appropriate credentials object at Rails boot time. If only `credential_type` is set, credential parameters fall back to environment variables (see [Client: Environment Variables](client.md#environment-variables)).
406
+
407
+ **Logger behavior:**
408
+
409
+ - If not set, defaults to `Rails.logger`
410
+ - Set to a custom logger to override
411
+ - Set to `false` to disable logging entirely
412
+
413
+ ## Configuration Precedence
414
+
415
+ When resolving configuration values, Busybee follows this precedence (highest to lowest):
416
+
417
+ 1. **Explicit parameter** - Values passed directly to methods (e.g., `Client.new(cluster_address: "...")`)
418
+ 2. **Module configuration** - Values set via `Busybee.configure` or direct assignment
419
+ 3. **Rails configuration** - Values from `config.x.busybee.*` (when Rails is present)
420
+ 4. **Environment variables** - Fallback for supported options
421
+ 5. **Defaults** - Built-in default values
422
+
423
+ For credential parameters specifically, see [Client: Cluster Address Resolution](client.md#cluster-address-resolution).
424
+
425
+ ## Resetting Configuration
426
+
427
+ Configuration can be reset by setting attributes to `nil`:
428
+
429
+ ```ruby
430
+ Busybee.cluster_address = nil # Reverts to ENV or default
431
+ Busybee.credential_type = nil # Reverts to auto-detection
432
+ Busybee.logger = nil # Disables logging
433
+ ```
434
+
435
+ This is primarily useful in tests to ensure clean state between examples.
436
+
437
+ ## Worker Defaults
438
+
439
+ These settings control the default behavior of [workers](workers.md) and how they get jobs from the workflow engine. Each can be overridden per-worker via the [Worker DSL](workers.md#dsl-quick-reference) or at deploy time via [CLI/YAML configuration](workers.md#configuration-precedence).
440
+
441
+ #### `default_worker_mode`
442
+
443
+ Default worker mode for workers.
444
+
445
+ | | |
446
+ |--|--|
447
+ | **Type** | Symbol |
448
+ | **Default** | `:hybrid` |
449
+ | **Valid values** | `:polling`, `:streaming`, `:hybrid` |
450
+
451
+ ```ruby
452
+ Busybee.default_worker_mode = :polling
453
+ ```
454
+
455
+ See [Workers: Worker Modes](workers.md#worker-modes) for details on each mode.
456
+
457
+ #### `default_max_jobs`
458
+
459
+ Default maximum number of jobs to fetch per polling request.
460
+
461
+ | | |
462
+ |--|--|
463
+ | **Type** | Integer |
464
+ | **Default** | `25` |
465
+
466
+ ```ruby
467
+ Busybee.default_max_jobs = 50
468
+ ```
469
+
470
+ #### `default_buffer`
471
+
472
+ Whether streaming mode buffers jobs in memory by default.
473
+
474
+ | | |
475
+ |--|--|
476
+ | **Type** | Boolean |
477
+ | **Default** | `true` |
478
+
479
+ ```ruby
480
+ Busybee.default_buffer = false
481
+ ```
482
+
483
+ #### `default_buffer_throttle`
484
+
485
+ Default throttle delay for the job buffer in streaming or hybrid modes.
486
+
487
+ | | |
488
+ |--|--|
489
+ | **Type** | Numeric (milliseconds), Boolean, or `nil` |
490
+ | **Default** | `false` (no throttling) |
491
+
492
+ `false` disables throttling. `true` coerces to `0` (minimal throttle). A positive number sets the delay in milliseconds (sub-millisecond Floats accepted).
493
+
494
+ ```ruby
495
+ Busybee.default_buffer_throttle = 5 # 5ms throttle delay
496
+ ```
497
+
498
+ See [Workers: Buffer Throttle](workers.md#buffer-throttle) for guidance on choosing a value.
499
+
500
+ #### `default_backpressure_delay`
501
+
502
+ How long to wait after a backpressure error (`GRPC::ResourceExhausted`) before retrying.
503
+
504
+ | | |
505
+ |--|--|
506
+ | **Type** | Integer (milliseconds) or ActiveSupport::Duration |
507
+ | **Default** | `2_000` (2 seconds) |
508
+
509
+ ```ruby
510
+ Busybee.default_backpressure_delay = 10_000
511
+ ```
512
+
513
+ #### `default_input_required`
514
+
515
+ Whether worker inputs are required by default.
516
+
517
+ | | |
518
+ |--|--|
519
+ | **Type** | Boolean |
520
+ | **Default** | `true` |
521
+
522
+ ```ruby
523
+ Busybee.default_input_required = false # inputs are optional unless explicitly required
524
+ ```
525
+
526
+ #### `default_output_required`
527
+
528
+ Whether worker outputs are required by default.
529
+
530
+ | | |
531
+ |--|--|
532
+ | **Type** | Boolean |
533
+ | **Default** | `true` |
534
+
535
+ ```ruby
536
+ Busybee.default_output_required = false
537
+ ```
538
+
539
+ #### `shutdown_on_errors`
540
+
541
+ Exception classes that trigger a graceful worker shutdown when raised during `perform`. Applies to all workers in addition to any per-worker `shutdown_on` declarations.
542
+
543
+ | | |
544
+ |--|--|
545
+ | **Type** | Array of Exception classes (or a single class, which is coerced to an Array) |
546
+ | **Default** | `[]` |
547
+
548
+ ```ruby
549
+ Busybee.shutdown_on_errors = [PG::ConnectionBad, Redis::ConnectionError]
550
+ ```
data/docs/grpc.md CHANGED
@@ -4,30 +4,36 @@ The `Busybee::GRPC` module contains generated protocol buffer classes from the Z
4
4
 
5
5
  ## When to Use This
6
6
 
7
- Most users should use the higher-level abstractions:
7
+ Most users should use one of Busybee's higher-level abstractions:
8
8
 
9
- - **Testing workflows?** Use `Busybee::Testing` (available now)
10
- - **Building applications?** Use `Busybee::Client` (coming in v0.2)
11
- - **Processing jobs?** Use `Busybee::Worker` (coming in v0.3)
9
+ - **Testing your workflows?** Busybee::Testing provides [RSpec matchers and helpers for BPMN files](./testing.md).
10
+ - **Building apps which manage process instances?** Busybee::Client provides a [Ruby-idiomatic API for all those operations](./client.md).
11
+ - **Processing jobs?** Busybee::Worker provides an [out-of-the-box job worker framework](./workers.md), akin to Sidekiq or Racecar.
12
12
 
13
- The GRPC layer is an escape hatch for edge cases where you need direct access to Zeebe APIs that the higher-level abstractions don't expose. Examples:
13
+ This GRPC layer is an escape hatch for any edge cases you may encounter which need direct access to Zeebe APIs that the higher-level abstractions don't expose. Examples might include:
14
14
 
15
15
  - Calling RPCs not yet wrapped by the Client (e.g., `MigrateProcessInstance`, `ModifyProcessInstance`)
16
16
  - Building custom tooling that needs low-level control
17
17
  - Debugging or experimenting with the Zeebe API directly
18
+ - Using this layer as a drop-in, 100%-compatible replacement for the discontinued [zeebe-client](https://github.com/zeebe-io/zeebe-client-ruby) gem
19
+
20
+ > Most users won't need this, as the Testing module, Client class, and Worker pattern cover most common use cases.
18
21
 
19
22
  ## Basic Usage
20
23
 
21
24
  ```ruby
25
+ # create a stub (connection to Zeebe gateway) by hand:
22
26
  require "busybee/grpc"
23
-
24
- # Create a stub (connection to Zeebe gateway)
25
27
  stub = Busybee::GRPC::Gateway::Stub.new(
26
28
  "localhost:26500",
27
29
  :this_channel_is_insecure
28
30
  )
29
31
 
30
- # Check cluster topology
32
+ # or, equivalently:
33
+ require "busybee/credentials"
34
+ stub = Busybee::Credentials::Insecure.new(cluster_address: "localhost:26500").grpc_stub
35
+
36
+ # example: check cluster topology:
31
37
  request = Busybee::GRPC::TopologyRequest.new
32
38
  response = stub.topology(request)
33
39
 
@@ -39,9 +45,41 @@ response.brokers.each do |broker|
39
45
  end
40
46
  ```
41
47
 
48
+ ## Authentication
49
+
50
+ For local development with an insecure connection, you can create a stub instance directly, as shown above. For TLS- or OAuth-secured clusters (like Camunda Cloud), while you _can_ construct appropriate channel credentials at the GRPC level (refer to the [grpc gem documentation](https://grpc.io/docs/languages/ruby/basics/) for details), it's easier to construct an instance of Busybee::Credentials and then obtain a correctly-configured stub instance directly from that:
51
+
52
+ ```ruby
53
+ require "busybee/credentials"
54
+
55
+ credentials = Busybee::Credentials::CamundaCloud.new(
56
+ client_id: "my-client-id", # these can also be configured by the Railtie
57
+ client_secret: "my-client-secret", # or by env vars; see Providing Credentials
58
+ cluster_id: "my-cluster-id", # in client.md for details
59
+ region: "my-cluster-region"
60
+ )
61
+
62
+ credentials.grpc_stub # will always return a stub instance correctly configured for CamundaCloud
63
+ ```
64
+
65
+ If you have manually or automatically configured a top-level set of credentials for the gem, you can always refer to it directly from anywhere in your application to get a stub instance:
66
+
67
+ ```ruby
68
+ # in config/application.rb or config/initializers/busybee.rb:
69
+ Busybee.configure do |config|
70
+ config.credentials = Busybee::Credentials::CamundaCloud.new(...)
71
+ # see client.md "Providing Credentials" for Railtie and env var configuration
72
+ end
73
+
74
+ # then, anywhere in application code:
75
+ Busybee.credentials.grpc_stub
76
+ ```
77
+
78
+ > We recommend _against_ storing or memoizing the return value of `credentials.grpc_stub`. The Credentials instance already memoizes it internally, so that it may handle updating or replacing it if needed.
79
+
42
80
  ## Reducing Verbosity
43
81
 
44
- If you're making many GRPC calls, you can include the module to use class names directly:
82
+ If you're making many GRPC calls, you can include the GRPC module, and then use the request class names directly:
45
83
 
46
84
  ```ruby
47
85
  require "busybee/grpc"
@@ -49,20 +87,20 @@ include Busybee::GRPC
49
87
 
50
88
  stub = Gateway::Stub.new("localhost:26500", :this_channel_is_insecure)
51
89
 
52
- response = stub.topology(TopologyRequest.new)
90
+ topology_response = stub.topology(TopologyRequest.new)
53
91
 
54
92
  request = CreateProcessInstanceRequest.new(
55
93
  bpmn_process_id: "order-fulfillment",
56
94
  variables: { order_id: "123" }.to_json
57
95
  )
58
- instance = stub.create_process_instance(request)
96
+ response = stub.create_process_instance(request)
59
97
  ```
60
98
 
61
99
  ## Available Classes
62
100
 
63
101
  The GRPC module exposes:
64
102
 
65
- - `Busybee::GRPC::Gateway::Stub` - The gRPC client stub for making calls
103
+ - `Busybee::GRPC::Gateway::Stub` - The gRPC client stub class for making calls
66
104
  - Request/response classes for each RPC (e.g., `TopologyRequest`, `DeployResourceRequest`, `CreateProcessInstanceRequest`)
67
105
  - Enum types and nested message types from the Zeebe proto
68
106
 
@@ -91,16 +129,3 @@ The Gateway service includes these RPCs:
91
129
  | `MigrateProcessInstance` | Migrate a process instance to a new version |
92
130
 
93
131
  See the [Zeebe gRPC API documentation](https://docs.camunda.io/docs/apis-tools/zeebe-api/) for full details on request/response structures.
94
-
95
- ## Authentication
96
-
97
- For local development with an insecure connection:
98
-
99
- ```ruby
100
- stub = Busybee::GRPC::Gateway::Stub.new(
101
- "localhost:26500",
102
- :this_channel_is_insecure
103
- )
104
- ```
105
-
106
- For Camunda Cloud or TLS-secured clusters, you'll need to construct appropriate channel credentials. The upcoming `Busybee::Client` will handle this automatically; at the GRPC level, refer to the [grpc gem documentation](https://grpc.io/docs/languages/ruby/basics/) for credential setup.