Skip to content

SegmentDestination is causing huge CPU spikes when blocked by LittleSnitch #152

@grzegorzkrukowski

Description

@grzegorzkrukowski

Describe the bug
When using LittleSnitch to block traffic to Segement.io from our application, we are getting huge CPU Spikes really often, and when entering foreground/background - basically every time the flush is called.

I think there are several problems in SegmentDestination:

  1. Storage can grow without limits - old events that are not sent are never removed.
  2. Storage is keeping files infinitely - which is causing a snowball effect for every sync.
  3. Flush logic is not well prepared for having a lot of data to work with.
    First of all, it read all the data from the filesystem every time it's called.
    Then for each of the files, it creates a network request straight away iterating over all of them - which in my case ends up being over 1500 requests created and failing in milliseconds. This is when CPU spikes are kicking in.
    The whole process is repeated every time the flush() is called and things are getting worse and worse over time when more un-send events are piling up in the storage.

To Reproduce
Steps to reproduce the behavior:

  1. Install LittleSnitch
  2. Block segment.io traffic in LittleSnitch
  3. Create around 100.000 tracked events in Segment
  4. Observe the CPUSpikes when flush logic is called.
  5. Log an enormous amount of network connections created during the flush() call.

Expected behavior

  1. If the user decides to block segment.io coming from our application using external software there should be no performance drop or CPU spikes coming out of this library.

  2. Storage should not grow infinitely - at some point, older events should be removed when newer events are added - there should be the maximum amount of files that are allowed to be cached for sending.

  3. flush() method should not go so aggressive with creating network events for all un-send files - instead it should either go one by one and read the next files only when the previous one succeeded or it should pre-check if segment batch API is reachable before trying to create a massive amount of requests.

Platform (please complete the following information):

  • Library Version in use: 1.2.2
  • Platform being tested: macOS
  • Integrations in use: Amplitude

Workaround
As for now, I am using an ugly workaround from this fork that simply deleted all failed events if the error is URLError.networkConnectionLost - which is the case for LittleSnitch.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions