-
Notifications
You must be signed in to change notification settings - Fork 10
Closed
Description
Describe the bug
We are migrating from the old SDK to the new one, but run into an issue where no events are received anymore.
I followed the migration guide and created a unit test to see if events are coming into the source, but (using the Debugger view on the source in Segment dashboard), no events are received.
To Reproduce
New code:
[Fact]
public async Task Can_track2()
{
var configuration = new Segment.Analytics.Configuration(
writeKey: "xxxxx",
flushAt: 1,
flushInterval: 1,
storageProvider: new InMemoryStorageProvider(),
useSynchronizeDispatcher: true
);
var analytics = new Segment.Analytics.Analytics(configuration);
analytics.Identify("user");
analytics.Track("TestEvent");
analytics.Flush();
await Task.Delay(15000);
}
Old code:
[Fact]
public async Task Can_track()
{
Segment.Analytics.Initialize("xxxxxx", new Config());
Segment.Analytics.Client.Track("user", "TestEvent");
await Segment.Analytics.Client.FlushAsync();
Segment.Analytics.Dispose();
}
Expected behavior
I see these events in the debugger view of the source, but it doesn't.
The 'old code' works, but using the new SDK, nothing happens.
Platform (please complete the following information):
- Library Version in use: 2.5.1
- Platform being tested: .NET 9 on Windows
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
remcoros commentedon Mar 11, 2025
I did some debugging, and created a ProxyHttpClientProvider and noticed that SegmentUrl() for the ingestion endpoint, and "DoPost" are never called.
What am I missing? I've read through the documentation and migration guides multiple times now, read most of the Github issues, but nothing points to me doing something wrong?
wenxi-zeng commentedon Mar 11, 2025
hi @remcoros thanks for reporting this. I did some investigation. looks like our SynchronizeDispatcher does not work well with the System.Net.Http HttpClient. the executor does not await for SendAsync to fetch settings, and resumes to update settings with empty values, which causes segment destination plugin to be disabled.
as a workaround, if you only use
useSynchronizeDispatcher
for unit tests purpose, you can add adefaultSettings
in config as below, so analytics will enable segment destination plugin even if fetch settings from remote failed:you should be able see events get into your segment debugger after adding the default settings. if you only want it for unit tests but do not need to see it in segment debugger, you can follow this unit test to setup a mockHttpClient.
if you want to use
useSynchronizeDispatcher
in production, I'd suggest against it, since this SDK is architectured to be async. events are written and flushed in a fire and forget manner. however, we do have customers want a sync flush especially for server use cases. you can do so by providingeventPipelineProvider: new SyncEventPipelineProvider()
in the config to convert flush from async to sync. in fact, if you useSyncEventPipelineProvider
, you no longer needawait Task.Delay(15000);
in your unit test.we are updating our documentations, and will be sure to include the above information in the migration guide.
remcoros commentedon Mar 12, 2025
@wenxi-zeng
unfortunately, that did not work.I tried with your example, with and without 'useSynchronizeDispatcher', with and without SyncEventPipelineProvider. But nothing I try seems to work.In all cases, just as before, the "DoPost" method of the ProxyHttpHandler is never called, so it looks like it is never flushing.Even if I use the default configuration (useSynchronizeDispatcher: false, and all other defaults as documented). And use "await Task.Delay(1000000)" in the unit test to keep it running for a while, events are never sent.Actually it did work, I forgot to remove "autoAddSegmentDestination: false".
Thanks for the workaround!
wenxi-zeng commentedon Mar 12, 2025
thanks for confirming @remcoros! I have created an internal ticket for SynchronizeDispatcher issue. we will take a look at the root cause of SynchronizeDispatcher at a later time.
remcoros commentedon Mar 12, 2025
@wenxi-zeng Still having issues.
I'm now trying this in a live environment (without synchronous dispatcher), but events are not uploaded again.
This is the configuration:
Here is the full log (replaced writekey with 'xxxxxxxx'):
I noticed a difference with my earlier unit test, where I got some message about uploaded events, that are missing now.
Also, adding the "defaultSettings" work-around seems to not help in this case.
remcoros commentedon Mar 12, 2025
Also, I really don't understand the design of the Analytics class. According to the documentation, it should be a scoped service. But I looked at the source, and it looks like all things like the store, dispatchers, etc. are created new each time the Analytics class is created.
That means, for every http request, it creates a new instance and initializes everything new. Looking at the logs, it looks like this is indeed the case (all the "Analytics starting = False/True" logs). It also does a request to 'cdn-settings.segment.com' multiple times (for each http request?).
Isn't that extremely inefficient to do for every http request (especially under high load)?
remcoros commentedon Mar 12, 2025
I'm going back to use the old SDK. I've spent way too much time on this (twice now), and I feel the design of the new SDK is completely broken and inefficient for HTTP API / backend scenarios.
wenxi-zeng commentedon Mar 12, 2025
@remcoros you're right that this library should be used as singleton. we have realized the discrepancies on the docs and how misleading it is, and is actively working on the docs. the updated docs should be live in 2 weeks.
for the issue you're currently experiencing, it looks like you're using the default value of
flushAt
andflushInterval
(see the default values here). by default, it flushes at every 20 events or every 30 seconds. if these threshold are not met, no flush would happen. you can set theflushAt = 1
to flush at a per event basis, or write your own flush policy to flush at the time you desired, or useanalytics.Flush()
to force a flush (need to provide sync event pipeline if you want to wait for it complete).remcoros commentedon Mar 12, 2025
I've let the project run for several minutes, and according to the logs it does try to flush every 30 seconds, but no events are sent.
I've given up for now. This was the 2nd attempt of trying to migrate to the new SDK to no avail and have no time left to dive deep or do testing anymore for this. Maybe in the future with updated documentation and samples we can give it another try. But for now we'll be using the old SDK with our current (and already working) solution of pushing tracking to a background queue.
Thanks for your help!