nats-io / nats-server

High-Performance server for NATS.io, the cloud and edge native messaging system.
https://nats.io
Apache License 2.0
15.97k stars 1.41k forks source link

nats-server panic when create a stream with a wrong mapping destination #5570

Closed AetheWu closed 4 months ago

AetheWu commented 4 months ago

Observed behavior

We use nats-go sdk create a stream with below options:

jetstream.StreamConfig {
  Sources: []*jetstream.StreamSource{
            {
                Name: "mapping",
                SubjectTransforms: []jetstream.SubjectTransformConfig{
                    {
                        Source:     "events.*",
                        Destination: "events.{{wildcard(1)}}{{split(3,1)}}",
                    },
                },
            },
        }
}

The nats-server panic with below errors and is no longer running :

[94] 2024/06/20 07:57:37.684644 [ERR] Unable to get subject transform for source: invalid mapping destination: too many arguments passed to the function in {{wildcard(1)}}{{split(3,1)}}
fatal error: sync: Unlock of unlocked RWMutex

Expected behavior

do not panic

Server and client version

nats-server version: 2.10.16 nats-client: nats.go-1.36.0

Host environment

Deploy with official helm charts

Steps to reproduce

No response

AetheWu commented 4 months ago

In addition, how to use nats.go to create stream partitions

derekcollison commented 4 months ago

I quickly created a test under server/jetstream_test.go and added it and it does not fail, but does provide an error. I tested on main, release/v2.10.17 and release/v2.10.16 branches.

// https://github.com/nats-io/nats-server/issues/5570
func TestJetStreamBadSubjectMappingStream(t *testing.T) {
    s := RunBasicJetStreamServer(t)
    defer s.Shutdown()

    // Client for API requests.
    nc, js := jsClientConnect(t, s)
    defer nc.Close()

    _, err := js.AddStream(&nats.StreamConfig{
        Name: "test",
        Sources: []*nats.StreamSource{
            {
                Name: "mapping",
                SubjectTransforms: []nats.SubjectTransformConfig{
                    {
                        Source:      "events.*",
                        Destination: "events.{{wildcard(1)}}{{split(3,1)}}",
                    },
                },
            },
        },
    })
    require_NoError(t, err)
}
derekcollison commented 4 months ago

Although I do see a logic error @jnmoyne that you unlock the stream but do not return, so I can see where this would fail but the example above does not recreate it that error.

derekcollison commented 4 months ago

ok key is it has to be an update of an existing stream, not new one. I see it.

jnmoyne commented 4 months ago

The mistake in your transform is that you need to put a '.' between the two transform functions (i.e. between {{wildcard(1)}} and {{split(3,1)}}).

And obviously it should handle that error better (thanks @derekcollison for taking care of that before I got to it!).