cloudflare-email 0.4.1 → 0.4.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b53307e62ade70f522e0fcb5705e11552e9718914d02bea8754a11653b15349a
4
- data.tar.gz: 692c09a19fcb4ccd9295ccb692a19bf02aba3176b107c8500e5450b100ce1df3
3
+ metadata.gz: b10971753d5d8d65bfafc658d3b8bc38553de251215c27097076d53593131813
4
+ data.tar.gz: b341d781aa6167beecf164915c6672e05c90c8888d76edd90c85e40413a84ad4
5
5
  SHA512:
6
- metadata.gz: 43da0e85cde52970e696d5a2dfd74f03c0f39f5ea7d66e33cd28ec2bb58e5872c57db7f5dbc010ab85ad43312de9c9abcf2eed31a65e01f78fed8b6de164483b
7
- data.tar.gz: a38902643ce082d656a01b7d91a34e70f95f15d66de6fd06e1fe7502461ae6d155a64edcea780155dd9b00b055635a3b10d5a0e9d8cbf2d077e1a7782742b193
6
+ metadata.gz: ec423d963ffeb2a3a126067360131dafc0bfd0bd4a6f25c4460fdadc03920a7af35bd21d8421c7ea827daa9cb6de36258ea6ed2932a58dbb30c4b92e0e22ab08
7
+ data.tar.gz: ce03d941227cd672b26c283c973773c1875e5ba63192671f002c9984877db8f4a28c5a40f2def54284bdfd6e031357d8f442da4958c23efb3bbac8c419b336a0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.2 — 2026-10-12
4
+
5
+ Released alongside Mailbox Kit 0.1.1, which it now requires.
6
+
7
+ - Mailbox Kit: stop aborting Rails' production attribute preloader. Without a
8
+ Mailbox Kit tenant context, `connection_pool` raised
9
+ `TenantConnectionUnavailable`; Rails 8.1's `active_record.define_attribute_methods`
10
+ initializer asks every model for `connection_pool.schema_reflection` inside one
11
+ rescue, so the first Mailbox Kit model ended the loop (printing "Failed to
12
+ define attribute methods ...") and every model after it — including the host's
13
+ own — was left to define its attribute methods on first use. `connection_pool`
14
+ now returns a placeholder that answers only `schema_reflection` (empty, so
15
+ nothing is defined for Mailbox Kit models) and raises the same
16
+ `TenantConnectionUnavailable` for anything else. Queries, construction and
17
+ connection checkout without a context still fail closed.
18
+ - Mailbox Kit: upload the raw email before opening a transaction. `InboundEmail.persist`
19
+ stored the bytes inside its own transaction, and `Mailboxes.receive(source:)` and
20
+ `Ingress::VerifiedMessage#receive_into_mailbox!` called it inside the membership
21
+ transaction, so the storage round trip (an S3 PUT in production) ran while the
22
+ transaction held the database's write lock. On SQLite with immediate transactions
23
+ that stalled every other writer to the tenant. Now the bytes upload first and only
24
+ rows are written under the lock. New `InboundEmail.prepare(...)` returns an
25
+ uploaded-but-unsaved delivery whose `#persist` writes the rows, for hosts with their
26
+ own transaction. A duplicate uploads nothing. Bytes no committed row names (a rolled
27
+ back delivery, or one a concurrent delivery beat) are deleted once the transaction
28
+ has finished. The duplicate checks under the lock bypass the query cache, which
29
+ would otherwise repeat the answer from before the upload.
30
+
3
31
  ## 0.4.1 — 2026-10-06
4
32
 
5
33
  - Report the provider's own reason when a refused request returns a body that
@@ -44,9 +44,17 @@ module Cloudflare
44
44
  # missing membership without scheduling Rails processing again.
45
45
  def receive_into_mailbox!
46
46
  result = nil
47
- Mailboxes.receive(recipient: envelope.fetch("to")) do
48
- result = persist_rails_record
49
- result.record
47
+ prepared = nil
48
+ recipient = envelope.fetch("to")
49
+ # Upload before the membership transaction opens (see InboundEmail).
50
+ Mailboxes.with_recipient(recipient: recipient) { prepared = prepare_rails_record }
51
+ begin
52
+ Mailboxes.receive(recipient: recipient) do
53
+ result = prepared.persist
54
+ result.record
55
+ end
56
+ ensure
57
+ Mailboxes.for_tenant(prepared.tenant_key) { prepared.discard } if prepared
50
58
  end
51
59
  result.record if result.created?
52
60
  end
@@ -54,8 +62,12 @@ module Cloudflare
54
62
  private
55
63
 
56
64
  def persist_rails_record
65
+ prepare_rails_record.persist
66
+ end
67
+
68
+ def prepare_rails_record
57
69
  require "mailbox_kit/inbound_email"
58
- MailboxKit::InboundEmail.persist(source: body, message_checksum: message_checksum,
70
+ MailboxKit::InboundEmail.prepare(source: body, message_checksum: message_checksum,
59
71
  message_id: stable_message_id, metadata: storage_metadata)
60
72
  end
61
73
 
@@ -1,5 +1,5 @@
1
1
  module Cloudflare
2
2
  module Email
3
- VERSION = "0.4.1"
3
+ VERSION = "0.4.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudflare-email
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cole
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 0.1.0
18
+ version: 0.1.1
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: 0.1.0
25
+ version: 0.1.1
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: base64
28
28
  requirement: !ruby/object:Gem::Requirement