- I started $by_event_type projection in my instance of EventStore.
- Then in my application I subscribed to $et-MyEventType stream.
- However, I noticed that my subscription gets silently dropped, if at the moment of creation there were no events of type “MyEvent”. I would expect to be at least informed about this fact.
- Moreover, I noticed that subscribing to an empty stream works fine (i.e. I could see it successfully handling incoming events). So it looks like there’s something wrong with the projection.
Which kind of subscription?
I use the C# Client and the function “SubscribeToStreamFrom” the piece of code (F#):
let lastCheckpoint = …
let handler = …
connection.SubscribeToStreamFrom(stream = “$et-MyEventType”, lastCheckpoint = lastCheckpoint, resolveLinkTos = true,
eventAppeared = Action<EventStoreCatchUpSubscription, ResolvedEvent>(handler))
ok so a catch up subscription. The reason I ask i there are 3 types of
Competing Consumers (connect to subscription)
Catchup Subscription (subscribefrom)
Live subscription (subscribe)
To clarify you are using a catch up subscription to a stream that does
not exist correct?
Are you connected to the varying events on the subscription? I would
imagine you would at least get a subscription dropped event
OK - sorry for providing too little details at first - still learning ;).
To answer the question:
Let’s make sure I use the words correctly: I intend to have a lot of streams for my events:
and they all are to contain homogeneous events (of type “MyEventType”). Subscribing to any of these works fine even if empty (== doesn’t exist at the moment of creating the subscription)
Moreover, sometimes I’d like to react to an event entering any of these streams - that’s why I enabled the projection. And it seems that the subscription to it gets lost if there are no events in any of “MyEventType-Idx” streams.
Thanks for the hint - I’ve added the subscription dropped handler and I could see it’s result a few seconds after creating the subscription (a text printed to a console).
Also: writing even a single event before creating the subscription results in the fact I couldn’t see any text in the console (== the subscription dropped event was not triggered).
Some more information:
Exception: System.AggregateException: One or more errors occurred. —> EventStore.ClientAPI.Exceptions.AccessDeniedException: Read access denied for stream ‘$et-MyEventType’.
I’m guessing the stream doesn’t exist until first event has been written? (as opposed to 1.0 behaviour that had a $stream-created event).
Its a system stream so admin read by default. You can change this by
setting its ACL in stream metadata
This piece of code:
let credential = SystemData.UserCredentials(“admin”, “changeit”)
let streamMetadata = StreamMetadata.Create(acl = StreamAcl("$all", “$all”, “$all”, “$all”, “$all”))
Async.AwaitTask(this.SetStreamMetadataAsync(streamName, ExpectedVersion.Any, streamMetadata, credential))
does it’s job (i.e. the subscription is established even for an empty “$et-…” stream). However, this requires admin rights, as a normal user can’t read/write the stream’s metadata.
I’ve done a further investigation: I modified my subscribe function to user admin rights as well. As a result, the subscription was created successfully.
Looks like by default the “$et-…” streams are available only to admins, while the first event changes the ACL to be readable by everyone.
Is that the expected behaviour ?
All streams that start with $ are by default only allowed to admins
you can change this behavior by editing the default
Sounds good - could you tell me how to provide these default settings ? The thing is I can’t find an example on how to do this.
I’ve tried viewing the $settings stream, but it doesn’t exist in my instance.
Also, I’ve tried running EventStore with --config option (–config=“C:\config.txt”). The content of my config.txt is as follows:
I’ve tried YAML as well, as I read this is the right format from v3 RC, but also no success:
Post it to the stream of default acls. Will update docs with an
example of this as it seems many have been confused by this.
@all what do you think about writing a default acl on startup to make
it a bit clearer so when people GET they actually get something?
I think that would make things more obvious.
However, this still requires to use admin rights. Is there maybe a way of changing the settings without using the privileges like a sort of a config file or similar ? (e.g. when I start a fresh instance, to make sure everything is set up correctly without the need to hardcode admin rights anywhere)
I can see that EventStore supports --config option, but can’t rally find an example. Could that be used in my case ?
No those settings are in $settings. As stated in docs you would only
need the admin privs the FIRST time you changed them (you could change
them to whatever user you wanted on the first time). To be fair its a
sensible default to only allow admins to change default acls
(otherwise any user could hijack you on startup)
Makes sense - just wanted to make sure.
All right - I know what I needed. Thanks for the help!