Repository navigation
Bump the wolverine group with 5 updates - #232
Merged
Merged
Conversation
Bumps Marten from 9.54.1 to 9.57.0 Bumps WolverineFx from 6.54.0 to 6.60.0 Bumps WolverineFx.Marten from 6.54.0 to 6.60.0 Bumps WolverineFx.RabbitMQ from 6.54.0 to 6.60.0 Bumps WolverineFx.RuntimeCompilation from 6.54.0 to 6.60.0 --- updated-dependencies: - dependency-name: Marten dependency-version: 9.57.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: wolverine - dependency-name: WolverineFx dependency-version: 6.60.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: wolverine - dependency-name: WolverineFx.Marten dependency-version: 6.60.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: wolverine - dependency-name: WolverineFx.RabbitMQ dependency-version: 6.60.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: wolverine - dependency-name: WolverineFx.RuntimeCompilation dependency-version: 6.60.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: wolverine ... Signed-off-by: dependabot[bot] <support@github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Updated Marten from 9.54.1 to 9.57.0.
Release notes
Sourced from Marten's releases.
9.57.0
Highlights
ShouldDeleteorDeleteEvent<T>, used to lose its whole history to an empty snapshot. Compaction now leaves it alone and logs an information line. (#5797)IncludeStreamandIncludeEventsused to leave those rows in plain text and report success. (#5797)opts.Events.AutoDiscoverTagTypesturns off automatic DCB tag type registration, for stores that use strong-typed identifiers but not DCB. It's on by default, and explicitRegisterTagType<T>()calls work either way. Thanks to @gschuager for the report and the design. (#5806)EventStoreUsagereports the event store'sTenancyStyle, so a console can tell conjoined events from conjoined documents. (#5805)Action needed after upgrading
If you rely on masking for archived or skipped events: run the same
ApplyEventDataMaskingcall again. Data that was archived or skipped when you last ran it is still in plain text until you do.That call runs your rules again over everything the first pass reached. If a rule isn't safe to run twice, such as one that draws a new pseudonym, add
x.IsArchivedto anIncludeEventsfilter that still names the same subject:Never use
x.IsArchivedas the whole filter, because that masks every archived event in the store.If you compact streams: the deleted events can't be rebuilt from Marten. To find affected streams, replace
<schema>and run this, then restore those streams from a backup or from wherever an archiver copied them:An archiver closed over
IDocumentSessionwas never called for past compactions, so that copy won't exist.Behaviour changes
IncludeEventsnow includes archived events. A masking filter that needs only live events should add!x.IsArchived.IDocumentOperationsorIDocumentSessionnow throwsInvalidOperationExceptionbefore anything is queued. It used to be skipped silently, with the events deleted anyway. An archiver closed overIDocumentSessionis now called.ToParameterTypenow throws for an unmapped type where it used to return a character catch-all. An enum resolves through its underlying type, so along-backed enum givesBigint. Marten's own call sites are not affected.What's Changed
Full Changelog: JasperFx/marten@v9.56.0...V9.57.0
... (truncated)
9.56.0
What's Changed
Full Changelog: JasperFx/marten@V9.55.0...v9.56.0
9.55.0
Read before upgrading
Apps running under a Turkish or Azerbaijani culture (
tr-TR,az-AZ) with document types whose names contain an uppercaseI. Document aliases (#5778),DdlTemplatelookups and flat-table upsert function names (#5783) are now lowered with the invariant culture. Before this release, those cultures turnedIinto a dotlessı, so a document typeInvoicewas stored inmt_doc_ınvoice. From 9.55.0 it maps tomt_doc_invoice, and Marten will create that table empty. Rename the existing tables (and their upsert functions) to the invariant name before upgrading, or the existing documents will appear to be missing. Apps on any other culture are unaffected: the names they generate are unchanged.Behaviour change:
StoredDocument.Versionfor projection documents (#5773). For a mapping that usesUseVersionFromMatchingStreamwith revisions, the diagnostics version token is now<mt_version>:<mt_last_modified as epoch microseconds>(or an md5 of the document body when last-modified tracking is disabled). It used to bemt_versionalone, which did not change when the daemon rewrote the document at the same stream version. Anything that parsed the token as an integer must be updated. Undeleting a projection document through the diagnostics writer also no longer bumpsmt_versionpast the stream's version.Fixes worth calling out
x.Inner.Value, instead of falling back to the JSONB path.TrackConnections = TrackLevel.Verbose, amarten.append.eventactivity event is now emitted on every append route, including the Quick routes that are the V9 default. Expect more events per append than before.DatabaseSchemaNamethat is a reserved word or contains uppercase. Before, every schema apply after the first failed with42P07(weasel#750, contributed by @marc-RocketRez).StreamPagedByCursorwrites each page's bytes directly and disposes its pooled stream (#5776, @chrisbbe).What's Changed
New Contributors
Full Changelog: JasperFx/marten@v9.54.2...V9.55.0
9.54.2
What's Changed
New Contributors
Full Changelog: JasperFx/marten@V9.54.1...v9.54.2
Commits viewable in compare view.
Updated WolverineFx from 6.54.0 to 6.60.0.
Release notes
Sourced from WolverineFx's releases.
6.60.0
What's Changed
Full Changelog: JasperFx/wolverine@V6.59.1...V6.60.0
6.59.1
This is a patch release with two fixes. Upgrading is a package bump only: there is no schema change and no API change.
SQL Server: the inbox and outbox seek on their indexes again
sql_variant. The statements that mark envelopes as handled, reassign them, delete them and move them to the dead letter queue all filter on the envelope id. Weasel's generic command builder has no mapping forGuid, so it bound each id asDbType.Object, which SqlClient sends assql_variant. SQL Server then had to compareCONVERT_IMPLICIT(sql_variant, [id])on every row, which rules out a seek on theuniqueidentifierprimary key. Ids are now bound asuniqueidentifier, so each statement is a primary key seek.nvarchar.received_aton the inbox anddestinationon the outbox arevarchar(250)columns, but statements that filter on them bound the address asnvarchar. Under a SQL collation such asSQL_Latin1_General_CP1_CI_AS, the default on Azure SQL, that converts the column and defeats the index. The statements affected are the per-envelope updates and deletes, inbox recovery's page load, outbox loads by destination, the scheduled message updates and the duplicate check. They now bind the address asvarchar.DateTimeparameters kept only the date. The same generic mapping typedDateTimeasDbType.Date. The message store now lets SqlClient type both values itself.sql_variantand that no plan converts an indexed envelope column. The fullSqlServerTestssuite passes (721 tests, 2 skipped).Guidassql_variant) and JasperFx/weasel#759 (DateTimeasdate). Wolverine works around both on its own, so this release doesn't wait for a Weasel release.The
runcommand no longer blocks a thread pool threadruncommand waited for shutdown by blocking a thread pool thread for the whole life of the application. That matters when a container's CPU limit is below one core.ProcessorCountis then 1, so the thread pool's minimum is one thread, and theruncommand held it. After that, every burst of work had to wait for the pool to add a thread, about 500 ms each time. The reporter saw a 200 msTask.Delayloop wake up as much as about 950 ms late on Azure Container Apps.runcommand now awaits shutdown instead of blocking. It still listens for the same three signals:ApplicationStopping, Ctrl+C, and the assembly load context unloading.AutoStartHost/WebApplicationFactorypath),RunJasperFxCommands()used to block the calling thread. It now returns a task that completes when the host shuts down.RunJasperFxCommands()orRunWolverineCommands(), whatever its persistence or transport.Full Changelog: JasperFx/wolverine@V6.59.0...V6.59.1
6.59.0
New
ScheduledMessageSummary.SagaIdreports the saga id carried by each scheduled envelope. The newScheduledMessageQuery.SagaIdlimitsQueryAsyncandCancelAsyncto one saga's scheduled messages, such as its pending timeouts.PageSizeandTotalCountstay exact. On a large scheduled backlog, narrow the query withMessageTypeor an execution-time window as well.CancelAsyncwith aSagaIdthat matches nothing cancels nothing.PageSize <= 0as "read every match", as the RDBMS stores already did.WolverineFx.AI'sAddLlmCallouts()now works underTypeLoadMode.Staticwhen the application's pre-generated code was written without it. A library can ship its own static codegen and a host can add LLM callouts on top. In Static mode, callouts run on a pre-built handler that needs no generated code. Every other mode is unchanged.LlmCalloutOptions.ConfigureChain(Action<HandlerChain>)customizes the callout chain in any mode.IHandlerPolicydoesn't reach the pre-built handler.DeduplicateCalloutsis refused at startup in Static mode, because deduplication is woven into generated code.Fixes
IHost.StopAsync()cancels mid-flight is no longer logged as a send failure. Azure Service Bus hands the runtime's cancellation token to the SDK, so an orderly shutdown used to produce two Error lines for a batch that was never lost. A durable agent now logs it at Information, because the envelopes stay in the outbox and are recovered on restart. A non-durable agent logs it at Warning, because those messages were not sent. A shutdown cancellation no longer counts toward the circuit breaker or the sending failure policies. A cancellation while the application is still running, or any other exception during shutdown, is still logged at Error.6.58.0
New
GH-5279 (#5280, #5282): New opt-in
Durability.UseTransactionScopedDurabilityPassLockfor PostgreSQL. The serverless durability pass takes a transaction-scoped advisory lock (pg_try_advisory_xact_lock) instead of a session lock. This makes the pass lock safe behind a transaction-mode pooler such as PgBouncer or Supabase's pooler, where a session lock can leak onto a pooled connection or be held by two passes at once. #5282 hardens it:TransactionScopeidle_in_transaction_session_timeoutcan no longer drop the lock in the middle of a passWolverine also logs a one-time warning when the store doesn't support the setting, or when extension steps such as Marten's projection catch-up run under the open lock transaction. That open transaction can stall Marten's gap detection, which is tracked in JasperFx/marten#5791. See the serverless guide.
Fixes
ProcessingFailureinstead ofReceivedwhen its inbox could not store a batch. The sender keeps the batch and retries it, and a late duplicate is deduplicated by id. gRPC listeners can't be durable, so they aren't affected. A guard test now pins that.Durability.EnableInboxPartitioning, PostgreSQL's durable inbox now refuses a redelivery whose identity was already handled. Before, the kept Handled row sat in a different partition and didn't collide, so the redelivery was handled a second time. This completes the stable-id deduplication from 6.57.0 for partitioned inboxes.6.57.0
New
XmlSerializer, and they no longer have to switch to JSON before a migration to Wolverine can start. Every NServiceBus interop endpoint (Rabbit MQ, Azure Service Bus, Amazon SQS and SNS, and the SQL Server and PostgreSQL NServiceBus transports) now reads both JSON and XML, choosing per message from theNServiceBus.ContentTypeheader. To send XML, use the newNServiceBusXmlSerializer:.UseNServiceBusInterop().DefaultSerializer(new NServiceBusXmlSerializer()). Because one endpoint reads both formats, NServiceBus endpoints can also move from XML to JSON gradually. See XML Serialization with NServiceBus.Informationinstead of as an error.WolverineHttpOptions.RejectUnparseableHeaderValuesanswers 400 with ProblemDetails when a[FromHeader]value can't be parsed.Fixes
UseForReplies(). Wolverine used to give NServiceBus its ownwolverine.response.{guid}system queue as the reply address, which NServiceBus can't reach, so every reply ended up in NServiceBus's error queue.DurabilityAgent.StopAsync()now cancels its in-flight durability command and waits for it to finish. Before, a command still running at shutdown could outlive the host and fail against a disposed data source.WithDbContextAbstractionnow reuses the tenant DbContext, so repository writes, the save and outbox enrollment all use one context. This could previously fail code generation.[FromHeader]header binds the comma-joined values instead of answering 500.AndPauseProcessing()chained afterScheduleRetryIndefinitely()/RequeueIndefinitely()now apply, including to the open-ended attempts after the listed delays.Dependencies
Docs and build
./build.sh LocalGateruns every CI suite on one machine (GH-5125, #5246). The CI suites are rebalanced to stay under the 20 minute job limit (#5267), and the scaffold tests now pass on Windows (GH-5255, #5264).6.56.0
New
opts.UseHttpTransport()registers the HTTP transport insideUseWolverine().http/httpsURIs then resolve inListenForMessagesFrom(),PublishMessage<T>().To(uri), and runtimeEndpointFor()/ToDestination(). Before this, the transport was only registered byToHttpEndpoint(), and any otherhttpURI failed withUnknown Transport scheme 'http'./_wolverine/invokenow answers 415 instead of 500 for a content type with no registered serializer.Fixes
IHost.StopAsync()and throwObjectDisposedExceptionagainst a disposedNpgsqlDataSource.DeferAsync()used to call back into the receiver inline, so the failed inbox write and the defer recursed. A deferred Kafka envelope now goes back to the receiver on its own task after a short pause, and only while the listener is running. After a stop or inbox-recovery pause, its uncommitted offset brings it back. Because Kafka has no native requeue, aRequeueerror policy on a Kafka endpoint now redelivers after about one second instead of immediately./_wolverine/invokecould delete an outgoing envelope that was never received. HTTP transport responses are now disposed.6.55.1
Fixes
DatabaseBatchCommandExceptionand logged as an Error. Genuine SQL/connection failures are still reported.HttpEndpointaimed at/_wolverine/invokein its default (buffered) mode now delivers by posting each envelope individually, instead of receiving a 415 for every batch and retrying forever./batch/{queue}and.SendInline()endpoints are unchanged.6.55.0
Highlights
WolverineFx.Bobcat is out of alpha, on Bobcat 1.0.0 (#5222, #5229). Bobcat 1.0.0 shipped tonight, and
WolverineFx.BobcatandWolverineFx.Bobcat.EventModelnow publish as stable 6.55.0 instead of-alpha.1.WolverineFx.Bobcat.Httpstays6.55.0-alpha.1until Alba 9 ships stable, because a stable package cannot depend on Alba 9.0.0-rc.2. A spec project thatwrite-specsgenerates with no--wolverine-versionpins the stableWolverineFx.Bobcat(#5222, #5223).MessageCausedBynames your handler (#5224, #5225).IWolverineObserver.MessageCausedByreported the generated handler class (Internal.Generated.WolverineHandlers.StartTripHandler939323516). It now reports the handler you wrote (TripService.StartTripHandler), the same string as themessage.handlerspan tag, resolved at codegen time. Code generated by an earlier version keeps working through the old overload.CosmosDB sagas start with a conditional create (#5221, thanks @thechucklingatom). A second start message for an existing saga id used to silently overwrite the running saga. It now fails with the
SagaConcurrencyExceptionthat Marten, Azure Blob and S3 already raise, so oneOnException<SagaConcurrencyException>()policy covers every provider.Fixes
ListeningAgent.StartAsyncis serialized, and deliveries are deferred to a drainedBufferedReceiver(#5228)CancellationTokenSource(#5226)Dependencies
Originno longer raises aSourceDisagreement)Full Changelog: JasperFx/wolverine@V6.54.0...V6.55.0
Commits viewable in compare view.
Updated WolverineFx.Marten from 6.54.0 to 6.60.0.
Release notes
Sourced from WolverineFx.Marten's releases.
6.60.0
What's Changed
Full Changelog: JasperFx/wolverine@V6.59.1...V6.60.0
6.59.1
This is a patch release with two fixes. Upgrading is a package bump only: there is no schema change and no API change.
SQL Server: the inbox and outbox seek on their indexes again
sql_variant. The statements that mark envelopes as handled, reassign them, delete them and move them to the dead letter queue all filter on the envelope id. Weasel's generic command builder has no mapping forGuid, so it bound each id asDbType.Object, which SqlClient sends assql_variant. SQL Server then had to compareCONVERT_IMPLICIT(sql_variant, [id])on every row, which rules out a seek on theuniqueidentifierprimary key. Ids are now bound asuniqueidentifier, so each statement is a primary key seek.nvarchar.received_aton the inbox anddestinationon the outbox arevarchar(250)columns, but statements that filter on them bound the address asnvarchar. Under a SQL collation such asSQL_Latin1_General_CP1_CI_AS, the default on Azure SQL, that converts the column and defeats the index. The statements affected are the per-envelope updates and deletes, inbox recovery's page load, outbox loads by destination, the scheduled message updates and the duplicate check. They now bind the address asvarchar.DateTimeparameters kept only the date. The same generic mapping typedDateTimeasDbType.Date. The message store now lets SqlClient type both values itself.sql_variantand that no plan converts an indexed envelope column. The fullSqlServerTestssuite passes (721 tests, 2 skipped).Guidassql_variant) and JasperFx/weasel#759 (DateTimeasdate). Wolverine works around both on its own, so this release doesn't wait for a Weasel release.The
runcommand no longer blocks a thread pool threadruncommand waited for shutdown by blocking a thread pool thread for the whole life of the application. That matters when a container's CPU limit is below one core.ProcessorCountis then 1, so the thread pool's minimum is one thread, and theruncommand held it. After that, every burst of work had to wait for the pool to add a thread, about 500 ms each time. The reporter saw a 200 msTask.Delayloop wake up as much as about 950 ms late on Azure Container Apps.runcommand now awaits shutdown instead of blocking. It still listens for the same three signals:ApplicationStopping, Ctrl+C, and the assembly load context unloading.AutoStartHost/WebApplicationFactorypath),RunJasperFxCommands()used to block the calling thread. It now returns a task that completes when the host shuts down.RunJasperFxCommands()orRunWolverineCommands(), whatever its persistence or transport.Full Changelog: JasperFx/wolverine@V6.59.0...V6.59.1
6.59.0
New
ScheduledMessageSummary.SagaIdreports the saga id carried by each scheduled envelope. The newScheduledMessageQuery.SagaIdlimitsQueryAsyncandCancelAsyncto one saga's scheduled messages, such as its pending timeouts.PageSizeandTotalCountstay exact. On a large scheduled backlog, narrow the query withMessageTypeor an execution-time window as well.CancelAsyncwith aSagaIdthat matches nothing cancels nothing.PageSize <= 0as "read every match", as the RDBMS stores already did.WolverineFx.AI'sAddLlmCallouts()now works underTypeLoadMode.Staticwhen the application's pre-generated code was written without it. A library can ship its own static codegen and a host can add LLM callouts on top. In Static mode, callouts run on a pre-built handler that needs no generated code. Every other mode is unchanged.LlmCalloutOptions.ConfigureChain(Action<HandlerChain>)customizes the callout chain in any mode.IHandlerPolicydoesn't reach the pre-built handler.DeduplicateCalloutsis refused at startup in Static mode, because deduplication is woven into generated code.Fixes
IHost.StopAsync()cancels mid-flight is no longer logged as a send failure. Azure Service Bus hands the runtime's cancellation token to the SDK, so an orderly shutdown used to produce two Error lines for a batch that was never lost. A durable agent now logs it at Information, because the envelopes stay in the outbox and are recovered on restart. A non-durable agent logs it at Warning, because those messages were not sent. A shutdown cancellation no longer counts toward the circuit breaker or the sending failure policies. A cancellation while the application is still running, or any other exception during shutdown, is still logged at Error.6.58.0
New
GH-5279 (#5280, #5282): New opt-in
Durability.UseTransactionScopedDurabilityPassLockfor PostgreSQL. The serverless durability pass takes a transaction-scoped advisory lock (pg_try_advisory_xact_lock) instead of a session lock. This makes the pass lock safe behind a transaction-mode pooler such as PgBouncer or Supabase's pooler, where a session lock can leak onto a pooled connection or be held by two passes at once. #5282 hardens it:TransactionScopeidle_in_transaction_session_timeoutcan no longer drop the lock in the middle of a passWolverine also logs a one-time warning when the store doesn't support the setting, or when extension steps such as Marten's projection catch-up run under the open lock transaction. That open transaction can stall Marten's gap detection, which is tracked in JasperFx/marten#5791. See the serverless guide.
Fixes
ProcessingFailureinstead ofReceivedwhen its inbox could not store a batch. The sender keeps the batch and retries it, and a late duplicate is deduplicated by id. gRPC listeners can't be durable, so they aren't affected. A guard test now pins that.Durability.EnableInboxPartitioning, PostgreSQL's durable inbox now refuses a redelivery whose identity was already handled. Before, the kept Handled row sat in a different partition and didn't collide, so the redelivery was handled a second time. This completes the stable-id deduplication from 6.57.0 for partitioned inboxes.6.57.0
New
XmlSerializer, and they no longer have to switch to JSON before a migration to Wolverine can start. Every NServiceBus interop endpoint (Rabbit MQ, Azure Service Bus, Amazon SQS and SNS, and the SQL Server and PostgreSQL NServiceBus transports) now reads both JSON and XML, choosing per message from theNServiceBus.ContentTypeheader. To send XML, use the newNServiceBusXmlSerializer:.UseNServiceBusInterop().DefaultSerializer(new NServiceBusXmlSerializer()). Because one endpoint reads both formats, NServiceBus endpoints can also move from XML to JSON gradually. See XML Serialization with NServiceBus.Informationinstead of as an error.WolverineHttpOptions.RejectUnparseableHeaderValuesanswers 400 with ProblemDetails when a[FromHeader]value can't be parsed.Fixes
UseForReplies(). Wolverine used to give NServiceBus its ownwolverine.response.{guid}system queue as the reply address, which NServiceBus can't reach, so every reply ended up in NServiceBus's error queue.DurabilityAgent.StopAsync()now cancels its in-flight durability command and waits for it to finish. Before, a command still running at shutdown could outlive the host and fail against a disposed data source.WithDbContextAbstractionnow reuses the tenant DbContext, so repository writes, the save and outbox enrollment all use one context. This could previously fail code generation.[FromHeader]header binds the comma-joined values instead of answering 500.AndPauseProcessing()chained afterScheduleRetryIndefinitely()/RequeueIndefinitely()now apply, including to the open-ended attempts after the listed delays.Dependencies
Docs and build
./build.sh LocalGateruns every CI suite on one machine (GH-5125, #5246). The CI suites are rebalanced to stay under the 20 minute job limit (#5267), and the scaffold tests now pass on Windows (GH-5255, #5264).6.56.0
New
opts.UseHttpTransport()registers the HTTP transport insideUseWolverine().http/httpsURIs then resolve inListenForMessagesFrom(),PublishMessage<T>().To(uri), and runtimeEndpointFor()/ToDestination(). Before this, the transport was only registered byToHttpEndpoint(), and any otherhttpURI failed withUnknown Transport scheme 'http'./_wolverine/invokenow answers 415 instead of 500 for a content type with no registered serializer.Fixes
IHost.StopAsync()and throwObjectDisposedExceptionagainst a disposedNpgsqlDataSource.DeferAsync()used to call back into the receiver inline, so the failed inbox write and the defer recursed. A deferred Kafka envelope now goes back to the receiver on its own task after a short pause, and only while the listener is running. After a stop or inbox-recovery pause, its uncommitted offset brings it back. Because Kafka has no native requeue, aRequeueerror policy on a Kafka endpoint now redelivers after about one second instead of immediately./_wolverine/invokecould delete an outgoing envelope that was never received. HTTP transport responses are now disposed.6.55.1
Fixes
DatabaseBatchCommandExceptionand logged as an Error. Genuine SQL/connection failures are still reported.HttpEndpointaimed at/_wolverine/invokein its default (buffered) mode now delivers by posting each envelope individually, instead of receiving a 415 for every batch and retrying forever./batch/{queue}and.SendInline()endpoints are unchanged.6.55.0
Highlights
WolverineFx.Bobcat is out of alpha, on Bobcat 1.0.0 (#5222, #5229). Bobcat 1.0.0 shipped tonight, and
WolverineFx.BobcatandWolverineFx.Bobcat.EventModelnow publish as stable 6.55.0 instead of-alpha.1.WolverineFx.Bobcat.Httpstays6.55.0-alpha.1until Alba 9 ships stable, because a stable package cannot depend on Alba 9.0.0-rc.2. A spec project thatwrite-specsgenerates with no--wolverine-versionpins the stableWolverineFx.Bobcat(#5222, #5223).MessageCausedBynames your handler (#5224, #5225).IWolverineObserver.MessageCausedByreported the generated handler class (Internal.Generated.WolverineHandlers.StartTripHandler939323516). It now reports the handler you wrote (TripService.StartTripHandler), the same string as themessage.handlerspan tag, resolved at codegen time. Code generated by an earlier version keeps working through the old overload.CosmosDB sagas start with a conditional create (#5221, thanks @thechucklingatom). A second start message for an existing saga id used to silently overwrite the running saga. It now fails with the
SagaConcurrencyExceptionthat Marten, Azure Blob and S3 already raise, so oneOnException<SagaConcurrencyException>()policy covers every provider.Fixes
ListeningAgent.StartAsyncis serialized, and deliveries are deferred to a drainedBufferedReceiver(#5228)CancellationTokenSource(#5226)Dependencies
Originno longer raises aSourceDisagreement)Full Changelog: JasperFx/wolverine@V6.54.0...V6.55.0
Commits viewable in compare view.
Updated WolverineFx.RabbitMQ from 6.54.0 to 6.60.0.
Release notes
Sourced from WolverineFx.RabbitMQ's releases.
6.60.0
What's Changed
Full Changelog: JasperFx/wolverine@V6.59.1...V6.60.0
6.59.1
This is a patch release with two fixes. Upgrading is a package bump only: there is no schema change and no API change.
SQL Server: the inbox and outbox seek on their indexes again
sql_variant. The statements that mark envelopes as handled, reassign them, delete them and move them to the dead letter queue all filter on the envelope id. Weasel's generic command builder has no mapping forGuid, so it bound each id asDbType.Object, which SqlClient sends assql_variant. SQL Server then had to compareCONVERT_IMPLICIT(sql_variant, [id])on every row, which rules out a seek on theuniqueidentifierprimary key. Ids are now bound asuniqueidentifier, so each statement is a primary key seek.nvarchar.received_aton the inbox anddestinationon the outbox arevarchar(250)columns, but statements that filter on them bound the address asnvarchar. Under a SQL collation such asSQL_Latin1_General_CP1_CI_AS, the default on Azure SQL, that converts the column and defeats the index. The statements affected are the per-envelope updates and deletes, inbox recovery's page load, outbox loads by destination, the scheduled message updates and the duplicate check. They now bind the address asvarchar.DateTimeparameters kept only the date. The same generic mapping typedDateTimeasDbType.Date. The message store now lets SqlClient type both values itself.sql_variantand that no plan converts an indexed envelope column. The fullSqlServerTestssuite passes (721 tests, 2 skipped).Guidassql_variant) and JasperFx/weasel#759 (DateTimeasdate). Wolverine works around both on its own, so this release doesn't wait for a Weasel release.The
runcommand no longer blocks a thread pool threadruncommand waited for shutdown by blocking a thread pool thread for the whole life of the application. That matters when a container's CPU limit is below one core.ProcessorCountis then 1, so the thread pool's minimum is one thread, and theruncommand held it. After that, every burst of work had to wait for the pool to add a thread, about 500 ms each time. The reporter saw a 200 msTask.Delayloop wake up as much as about 950 ms late on Azure Container Apps.runcommand now awaits shutdown instead of blocking. It still listens for the same three signals:ApplicationStopping, Ctrl+C, and the assembly load context unloading.AutoStartHost/WebApplicationFactorypath),RunJasperFxCommands()used to block the calling thread. It now returns a task that completes when the host shuts down.RunJasperFxCommands()orRunWolverineCommands(), whatever its persistence or transport.Full Changelog: JasperFx/wolverine@V6.59.0...V6.59.1
6.59.0
New
ScheduledMessageSummary.SagaIdreports the saga id carried by each scheduled envelope. The newScheduledMessageQuery.SagaIdlimitsQueryAsyncandCancelAsyncto one saga's scheduled messages, such as its pending timeouts.PageSizeandTotalCountstay exact. On a large scheduled backlog, narrow the query withMessageTypeor an execution-time window as well.CancelAsyncwith aSagaIdthat matches nothing cancels nothing.PageSize <= 0as "read every match", as the RDBMS stores already did.WolverineFx.AI'sAddLlmCallouts()now works underTypeLoadMode.Staticwhen the application's pre-generated code was written without it. A library can ship its own static codegen and a host can add LLM callouts on top. In Static mode, callouts run on a pre-built handler that needs no generated code. Every other mode is unchanged.LlmCalloutOptions.ConfigureChain(Action<HandlerChain>)customizes the callout chain in any mode.IHandlerPolicydoesn't reach the pre-built handler.DeduplicateCalloutsis refused at startup in Static mode, because deduplication is woven into generated code.Fixes
IHost.StopAsync()cancels mid-flight is no longer logged as a send failure. Azure Service Bus hands the runtime's cancellation token to the SDK, so an orderly shutdown used to produce two Error lines for a batch that was never lost. A durable agent now logs it at Information, because the envelopes stay in the outbox and are recovered on restart. A non-durable agent logs it at Warning, because those messages were not sent. A shutdown cancellation no longer counts toward the circuit breaker or the sending failure policies. A cancellation while the application is still running, or any other exception during shutdown, is still logged at Error.6.58.0
New
GH-5279 (#5280, #5282): New opt-in
Durability.UseTransactionScopedDurabilityPassLockfor PostgreSQL. The serverless durability pass takes a transaction-scoped advisory lock (pg_try_advisory_xact_lock) instead of a session lock. This makes the pass lock safe behind a transaction-mode pooler such as PgBouncer or Supabase's pooler, where a session lock can leak onto a pooled connection or be held by two passes at once. #5282 hardens it:TransactionScopeidle_in_transaction_session_timeoutcan no longer drop the lock in the middle of a passWolverine also logs a one-time warning when the store doesn't support the setting, or when extension steps such as Marten's projection catch-up run under the open lock transaction. That open transaction can stall Marten's gap detection, which is tracked in JasperFx/marten#5791. See the serverless guide.
Fixes
ProcessingFailureinstead ofReceivedwhen its inbox could not store a batch. The sender keeps the batch and retries it, and a late duplicate is deduplicated by id. gRPC listeners can't be durable, so they aren't affected. A guard test now pins that.Durability.EnableInboxPartitioning, PostgreSQL's durable inbox now refuses a redelivery whose identity was already handled. Before, the kept Handled row sat in a different partition and didn't collide, so the redelivery was handled a second time. This completes the stable-id deduplication from 6.57.0 for partitioned inboxes.6.57.0
New
XmlSerializer, and they no longer have to switch to JSON before a migration to Wolverine can start. Every NServiceBus interop endpoint (Rabbit MQ, Azure Service Bus, Amazon SQS and SNS, and the SQL Server and PostgreSQL NServiceBus transports) now reads both JSON and XML, choosing per message from theNServiceBus.ContentTypeheader. To send XML, use the newNServiceBusXmlSerializer:.UseNServiceBusInterop().DefaultSerializer(new NServiceBusXmlSerializer()). Because one endpoint reads both formats, NServiceBus endpoints can also move from XML to JSON gradually. See XML Serialization with NServiceBus.Informationinstead of as an error.WolverineHttpOptions.RejectUnparseableHeaderValuesanswers 400 with ProblemDetails when a[FromHeader]value can't be parsed.Fixes
UseForReplies(). Wolverine used to give NServiceBus its ownwolverine.response.{guid}system queue as the reply address, which NServiceBus can't reach, so every reply ended up in NServiceBus's error queue.DurabilityAgent.StopAsync()now cancels its in-flight durability command and waits for it to finish. Before, a command still running at shutdown could outlive the host and fail against a disposed data source.WithDbContextAbstractionnow reuses the tenant DbContext, so repository writes, the save and outbox enrollment all use one context. This could previously fail code generation.[FromHeader]header binds the comma-joined values instead of answering 500.AndPauseProcessing()chained afterScheduleRetryIndefinitely()/RequeueIndefinitely()now apply, including to the open-ended attempts after the listed delays.Dependencies
Docs and build
./build.sh LocalGateruns every CI suite on one machine (GH-5125, #5246). The CI suites are rebalanced to stay under the 20 minute job limit (#5267), and the scaffold tests now pass on Windows (GH-5255, #5264).6.56.0
New
opts.UseHttpTransport()registers the HTTP transport insideUseWolverine().http/httpsURIs then resolve inListenForMessagesFrom(),PublishMessage<T>().To(uri), and runtimeEndpointFor()/ToDestination(). Before this, the transport was only registered byToHttpEndpoint(), and any otherhttpURI failed withUnknown Transport scheme 'http'./_wolverine/invokenow answers 415 instead of 500 for a content type with no registered serializer.Fixes
IHost.StopAsync()and throwObjectDisposedExceptionagainst a disposedNpgsqlDataSource.DeferAsync()used to call back into the receiver inline, so the failed inbox write and the defer recursed. A deferred Kafka envelope now goes back to the receiver on its own task after a short pause, and only while the listener is running. After a stop or inbox-recovery pause, its uncommitted offset brings it back. Because Kafka has no native requeue, aRequeueerror policy on a Kafka endpoint now redelivers after about one second instead of immediately./_wolverine/invokecould delete an outgoing envelope that was never received. HTTP transport responses are now disposed.6.55.1
Fixes
DatabaseBatchCommandExceptionand logged as an Error. Genuine SQL/connection failures are still reported.HttpEndpointaimed at/_wolverine/invokein its default (buffered) mode now delivers by posting each envelope individually, instead of receiving a 415 for every batch and retrying forever./batch/{queue}and.SendInline()endpoints are unchanged.6.55.0
Highlights
WolverineFx.Bobcat is out of alpha, on Bobcat 1.0.0 (#5222, #5229). Bobcat 1.0.0 shipped tonight, and
WolverineFx.BobcatandWolverineFx.Bobcat.EventModelnow publish as stable 6.55.0 instead of-alpha.1.WolverineFx.Bobcat.Httpstays6.55.0-alpha.1until Alba 9 ships stable, because a stable package cannot depend on Alba 9.0.0-rc.2. A spec project thatwrite-specsgenerates with no--wolverine-versionpins the stableWolverineFx.Bobcat(#5222, #5223).MessageCausedBynames your handler (#5224, #5225).IWolverineObserver.MessageCausedByreported the generated handler class (Internal.Generated.WolverineHandlers.StartTripHandler939323516). It now reports the handler you wrote (TripService.StartTripHandler), the same string as themessage.handlerspan tag, resolved at codegen time. Code generated by an earlier version keeps working through the old overload.CosmosDB sagas start with a conditional create (#5221, thanks @thechucklingatom). A second start message for an existing saga id used to silently overwrite the running saga. It now fails with the
SagaConcurrencyExceptionthat Marten, Azure Blob and S3 already raise, so oneOnException<SagaConcurrencyException>()policy covers every provider.Fixes
ListeningAgent.StartAsyncis serialized, and deliveries are deferred to a drainedBufferedReceiver(#5228)CancellationTokenSource(#5226)Dependencies
Originno longer raises aSourceDisagreement)Full Changelog: JasperFx/wolverine@V6.54.0...V6.55.0
Commits viewable in compare view.
Updated WolverineFx.RuntimeCompilation from 6.54.0 to 6.60.0.
Release notes
Sourced from WolverineFx.RuntimeCompilation's releases.
6.60.0
What's Changed
Full Changelog: JasperFx/wolverine@V6.59.1...V6.60.0
6.59.1
This is a patch release with two fixes. Upgrading is a package bump only: there is no schema change and no API change.
SQL Server: the inbox and outbox seek on their indexes again
sql_variant. The statements that mark envelopes as handled, reassign them, delete them and move them to the dead letter queue all filter on the envelope id. Weasel's generic command builder has no mapping forGuid, so it bound each id asDbType.Object, which SqlClient sends assql_variant. SQL Server then had to compareCONVERT_IMPLICIT(sql_variant, [id])on every row, which rules out a seek on theuniqueidentifierprimary key. Ids are now bound asuniqueidentifier, so each statement is a primary key seek.nvarchar.received_aton the inbox anddestinationon the outbox arevarchar(250)columns, but statements that filter on them bound the address asnvarchar. Under a SQL collation such asSQL_Latin1_General_CP1_CI_AS, the default on Azure SQL, that converts the column and defeats the in...Description has been truncated