Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Messages cannot be sent from Windows to Linux using the file share data bus #7043

Closed
abparticular opened this issue May 30, 2024 · 1 comment

Comments

@abparticular
Copy link
Contributor

abparticular commented May 30, 2024

Describe the bug

Description

When sending messages with databus properties from Windows to Linux, the FileShareDataBusImplementation throws a FileNotFoundException.

Expected behavior

The message is received without exceptions being thrown

Actual behavior

FileShareDataBusImplementation throws a FileNotFoundException.

Versions

All supported versions

Steps to reproduce

  • Base repro on https://docs.particular.net/samples/databus/file-share-databus/ sample
  • Modify sample to use Path.Combine to build path for databus in both sender/receiver
    • dataBus.BasePath(Path.Combine("..", "..", "..", "..", "storage"));
  • Run the sender on Windows
  • Run the receiver on Linux
  • Send a databus large message from sender to receiver

Note that this only affects Windows to Linux. Linux to Windows is not affected because Windows allows both forward and backward slashes to be present in a path.

Relevant log output

2024-05-30 10:49:15.648 WARN  Delayed Retry will reschedule message '6312e493-6682-48fc-b547-b180000d7a01' after a delay of 00:00:20 because of an exception:
System.IO.FileNotFoundException: Could not find file '/mnt/d/particular/samples/Version 8/file-share-databus_core_9/storage/2024-05-30_00\39240538-0c09-4fd4-876c-90fd457db3cc'.
File name: '/mnt/d/particular/samples/Version 8/file-share-databus_core_9/storage/2024-05-30_00\39240538-0c09-4fd4-876c-90fd457db3cc'
   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirError)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, UnixFileMode openPermissions, Int64& fileLength, UnixFileMode& filePermissions, Boolean failForSymlink, Boolean& wasSymlink, Func`4 createOpenException)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync)
   at NServiceBus.FileShareDataBusImplementation.Get(String key, CancellationToken cancellationToken) in /_/src/NServiceBus.Core/DataBus/FileShareDataBusImplementation.cs:line 25
   at NServiceBus.DataBusReceiveBehavior.Invoke(IIncomingLogicalMessageContext context, Func`2 next) in /_/src/NServiceBus.Core/DataBus/DataBusReceiveBehavior.cs:line 48
   at NServiceBus.DeserializeMessageConnector.Invoke(IIncomingPhysicalMessageContext context, Func`2 stage) in /_/src/NServiceBus.Core/Pipeline/Incoming/DeserializeMessageConnector.cs:line 32
   at NServiceBus.ProcessingStatisticsBehavior.Invoke(IIncomingPhysicalMessageContext context, Func`2 next) in /_/src/NServiceBus.Core/Performance/Statistics/ProcessingStatisticsBehavior.cs:line 25
   at NServiceBus.TransportReceiveToPhysicalMessageConnector.Invoke(ITransportReceiveContext context, Func`2 next) in /_/src/NServiceBus.Core/Pipeline/Incoming/TransportReceiveToPhysicalMessageConnector.cs:line 35
   at NServiceBus.RetryAcknowledgementBehavior.Invoke(ITransportReceiveContext context, Func`2 next) in /_/src/NServiceBus.Core/ServicePlatform/Retries/RetryAcknowledgementBehavior.cs:line 25
   at NServiceBus.MainPipelineExecutor.Invoke(MessageContext messageContext, CancellationToken cancellationToken) in /_/src/NServiceBus.Core/Pipeline/MainPipelineExecutor.cs:line 49
   at NServiceBus.MainPipelineExecutor.Invoke(MessageContext messageContext, CancellationToken cancellationToken) in /_/src/NServiceBus.Core/Pipeline/MainPipelineExecutor.cs:line 68
   at NServiceBus.LearningTransportMessagePump.ProcessFile(ILearningTransportTransaction transaction, String messageId, CancellationToken messageProcessingCancellationToken) in /_/src/NServiceBus.Core/Transports/Learning/LearningTransportMessagePump.cs:line 340
Exception details:
        Message ID: 6312e493-6682-48fc-b547-b180000d7a01
        Transport message ID: 73c70133-d9b2-4649-be32-f3c85f1fcda6
        Pipeline canceled: False

Additional Information

A proposed fix has been raised at:

Workarounds

An incoming message behaviour can be introduced on the Linux receiver to adjust the appropriate headers so that messages can be received

Create behavior:

class IncomingHeaderBehavior :
    Behavior<IIncomingPhysicalMessageContext>
{
    public override Task Invoke(IIncomingPhysicalMessageContext context, Func<Task> next)
    {
        var headers = context.Message.Headers;
        var databusHeaders = context.Message.Headers.Where(header => header.Key.StartsWith("NServiceBus.DataBus."));
        foreach (var header in databusHeaders)
        {
            headers[header.Key] = headers[header.Key].Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar);
        }

        return next();
    }
}

Register behavior:

endpointConfiguration.Pipeline.Register(typeof(IncomingHeaderBehavior), "Adjust Databus paths to use appropriate path separator");

Backported to

@jpalac
Copy link
Contributor

jpalac commented Jun 3, 2024

@orialmog FYI this issue has been fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants