I’ve stumbled upon an extremely weird issue here with states in
projection.
I have a continuous projection that captures a datetime string from
a category in its state. For example:
{
“MyTime”:
“2019-11-21T11:11:50+08:00”
}
All the datetimes from
my stream are stored in +08 time zone.
For some weird reason,
after a checkpoint is made (or when the projection is disabled), the state’s
datetime string timezone is converted to UTC +00:
{
“MyTime”:
“2019-11-21T03:11:50+00:00”
}
Notice how it also converts the actual hour as well as the timezone!
This baffles me because we’re just dealing with strings here … I
can’t imaging the projection engine converting all datetime strings to UTC by
itself!
My projection:
fromCategory(‘testdatestream’)
.foreachStream()
.when({
$init: function() {
return {
};
},
TimeChanged:
function(state, event) {
state.MyTime =
event.body.MyTime;
}
});
I can reproduce this in 5.0.1, 5.0.5, and 4.1.3 with the docker
image on my MacBook.
Reproduction Steps
- Start
docker container
docker pull eventstore/eventstore
docker volume create testtimeeventstore-data"
docker volume create testtimeeventstore-log"
docker run --name testtime-eventstore -it -p 2113:2113 -p 1113:1113 --mount source=testtime-eventstore-data,target=/var/lib/eventstore --mount source=testtime-eventstore-log,target=/var/log/eventstore eventstore/eventstore
- Create
20,000 events with unique categories
testdatestream-1
testdatestream-2
…
testdatestream-20000
each with unique timestamp in +08 timezone:
{
“MyTime”:
“2019-11-21T10:58:04+08:00”
}
I have a handy powershell script here that does it:
(1…20000) | %{ Invoke-WebRequest -Uri (“http://localhost:2113/streams/testdatestream” + $)
-Headers @{ “Content-Type” = “application/json”; “ES-EventType” = “TimeChanged”; “ES-EventId” =
[System.Guid]::NewGuid().ToString(); }
-Body ("{ "MyTime
“: `”" +
([DateTime]::UtcNow.AddSeconds($).ToLocalTime().ToString(“yyyy-MM-ddThh:mm:sszzz”))
- “`” }") -Method Post }
-
Create the
projection (see above projection snippet) -
Start the projection and
check the state for testdatestream-1. ** Notice the datetime string is in +08
time zone.**
- After a few
checkpoints have past, the datetime string is UPDATED to UTC +00 timezone!
(remember there’s only one event per stream in the category)
Why would a checkpoint update my state for no reason? Especially when it’s
just a datetime string?
-Stephen