Skip to content

Commit

Permalink
use different sampling algorithm (#185)
Browse files Browse the repository at this point in the history
  • Loading branch information
seemk authored Nov 27, 2023
1 parent cb9fdea commit 9a137be
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
28 changes: 22 additions & 6 deletions SplunkRumWorkspace/SplunkRum/SplunkRum/SessionBasedSampler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ struct BoolDecision: Decision {
class SessionBasedSampler: Sampler {

var probability: Double = 1.0
var upperBound: UInt32 = 0xFFFFFFFF
var currentlySampled: Bool?
var lock: Lock = Lock()

init(ratio: Double) {
probability = ratio
upperBound = UInt32(floor(ratio * Double(upperBound)))
observeSessionIdChange()
}

Expand All @@ -48,25 +50,23 @@ class SessionBasedSampler: Sampler {
private func observeSessionIdChange() {
addSessionIdCallback { [weak self] in
self?.lock.withLockVoid {
self?.currentlySampled = self?.shouldSampleNewSession()
self?.currentlySampled = self?.shouldSampleNewSession(sessionId: getRumSessionId())
}
}
}

private func getDecision() -> Decision {

if let currentlySampled = self.currentlySampled {
return BoolDecision(isSampled: currentlySampled)
}

let isSampled = self.shouldSampleNewSession()
let isSampled = self.shouldSampleNewSession(sessionId: getRumSessionId())
self.currentlySampled = isSampled
return BoolDecision(isSampled: isSampled)
}

/**Check if session will be sampled or not.**/
private func shouldSampleNewSession() -> Bool {

private func shouldSampleNewSession(sessionId: String) -> Bool {
var result = false

switch probability {
Expand All @@ -75,10 +75,26 @@ class SessionBasedSampler: Sampler {
case 1.0:
result = true
default:
result = Double.random(in: 0.0...1.0) <= probability
result = sessionIdValue(sessionId: sessionId) < self.upperBound
}

return result
}
}

func sessionIdValue(sessionId: String) -> UInt32 {
if sessionId.count < 32 {
return 0
}

var acc: UInt32 = 0

for i in stride(from: 0, to: sessionId.count, by: 8) {
let beginIndex = sessionId.index(sessionId.startIndex, offsetBy: i)
let endIndex = sessionId.index(beginIndex, offsetBy: 8, limitedBy: sessionId.endIndex) ?? sessionId.endIndex
let val = UInt32(sessionId[beginIndex ..< endIndex], radix: 16) ?? 0
acc ^= val
}

return acc
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ class SessionSamplingTests: XCTestCase {
resetRUM()
}

func testSessionIdValue() throws {
// The result value is taken from the JS RUM SDK for the given input
let value = sessionIdValue(sessionId: "c06947ed1f53b1a69be3c6899bc11a3e")
XCTAssertEqual(value, 3742903036)
}

/**Test Sending All Spans**/
func testSessionBasedSampling100Pct() throws {
// Forces RUM to reinitialze for testing
Expand Down

0 comments on commit 9a137be

Please sign in to comment.