@@ -28,14 +28,54 @@ func simpleNetworkCall() {
28
28
29
29
class SessionDelegate : NSObject , URLSessionDataDelegate , URLSessionTaskDelegate {
30
30
let semaphore = DispatchSemaphore ( value: 0 )
31
+ var callCount = 0
31
32
32
33
func urlSession( _ session: URLSession , task: URLSessionTask , didCompleteWithError error: Error ? ) {
33
34
semaphore. signal ( )
34
35
}
36
+
37
+ func urlSession(
38
+ _ session: URLSession ,
39
+ task: URLSessionTask ,
40
+ didFinishCollecting metrics: URLSessionTaskMetrics
41
+ ) {
42
+ semaphore. signal ( )
43
+ callCount += 1
44
+ print ( " delegate called " )
45
+ }
35
46
}
36
47
37
48
let delegate = SessionDelegate ( )
38
49
50
+ enum TimeoutError : Error {
51
+ case timeout
52
+ }
53
+
54
+ func waitForSemaphore( withTimeoutSecs: Int ) async {
55
+ do {
56
+ let _ = try await withThrowingTaskGroup ( of: Bool . self) { group in
57
+ group. addTask {
58
+ try await Task . sleep ( nanoseconds: UInt64 ( withTimeoutSecs) * NSEC_PER_SEC)
59
+ throw TimeoutError . timeout
60
+ }
61
+ group. addTask {
62
+ let semaphoreTask = Task {
63
+ DispatchQueue . global ( ) . async {
64
+ delegate. semaphore. wait ( )
65
+ }
66
+ }
67
+ await semaphoreTask. value
68
+ try Task . checkCancellation ( )
69
+ return true
70
+ }
71
+
72
+ return try await group. next ( ) !
73
+ }
74
+ } catch {
75
+ print ( " timed out waiting for semaphore " )
76
+ }
77
+ }
78
+
39
79
func simpleNetworkCallWithDelegate( ) {
40
80
let session = URLSession ( configuration: . default, delegate: delegate, delegateQueue: nil )
41
81
@@ -48,6 +88,38 @@ func simpleNetworkCallWithDelegate() {
48
88
delegate. semaphore. wait ( )
49
89
}
50
90
91
+ @available ( macOS 10 . 15 , iOS 15 . 0 , watchOS 8 . 0 , tvOS 15 . 0 , * )
92
+ func asyncNetworkCallWithTaskDelegate( ) async {
93
+ let session = URLSession ( configuration: . default)
94
+
95
+ let url = URL ( string: " http://httpbin.org/get " ) !
96
+ let request = URLRequest ( url: url)
97
+
98
+ do {
99
+ _ = try await session. data ( for: request, delegate: delegate)
100
+ } catch {
101
+ return
102
+ }
103
+
104
+ await waitForSemaphore ( withTimeoutSecs: 3 )
105
+ }
106
+
107
+ @available ( macOS 10 . 15 , iOS 15 . 0 , tvOS 13 . 0 , * )
108
+ func asyncNetworkCallWithSessionDelegate( ) async {
109
+ let session = URLSession ( configuration: . default, delegate: delegate, delegateQueue: nil )
110
+
111
+ let url = URL ( string: " http://httpbin.org/get " ) !
112
+ let request = URLRequest ( url: url)
113
+
114
+ do {
115
+ _ = try await session. data ( for: request)
116
+ } catch {
117
+ return
118
+ }
119
+
120
+ await waitForSemaphore ( withTimeoutSecs: 3 )
121
+ }
122
+
51
123
let spanProcessor = SimpleSpanProcessor ( spanExporter: StdoutSpanExporter ( isDebug: true ) )
52
124
OpenTelemetry . registerTracerProvider ( tracerProvider:
53
125
TracerProviderBuilder ( )
@@ -57,6 +129,21 @@ OpenTelemetry.registerTracerProvider(tracerProvider:
57
129
58
130
let networkInstrumentation = URLSessionInstrumentation ( configuration: URLSessionInstrumentationConfiguration ( ) )
59
131
60
- simpleNetworkCall ( )
132
+ print ( " making simple call " )
133
+ var callCount = delegate. callCount
61
134
simpleNetworkCallWithDelegate ( )
135
+ assert ( delegate. callCount == callCount + 1 )
136
+
137
+ if #available( macOS 10 . 15 , iOS 15 . 0 , watchOS 8 . 0 , tvOS 15 . 0 , * ) {
138
+ print ( " making simple call with task delegate " )
139
+ callCount = delegate. callCount
140
+ await asyncNetworkCallWithTaskDelegate ( )
141
+ assert ( delegate. callCount == callCount + 1 , " async task delegate not called " )
142
+
143
+ print ( " making simple call with session delegate " )
144
+ callCount = delegate. callCount
145
+ await asyncNetworkCallWithSessionDelegate ( )
146
+ assert ( delegate. callCount == callCount + 1 , " async session delegate not called " )
147
+ }
148
+
62
149
sleep ( 1 )
0 commit comments