|
1 | 1 | #if canImport(os)
|
2 |
| - import os.signpost |
| 2 | +import os.signpost |
3 | 3 |
|
4 |
| - extension AnyReducer { |
5 |
| - /// Instruments the reducer with |
6 |
| - /// [signposts](https://developer.apple.com/documentation/os/logging/recording_performance_data). |
7 |
| - /// Each invocation of the reducer will be measured by an interval, and the lifecycle of its |
8 |
| - /// effects will be measured with interval and event signposts. |
9 |
| - /// |
10 |
| - /// To use, build your app for Instruments (⌘I), create a blank instrument, and then use the "+" |
11 |
| - /// icon at top right to add the signpost instrument. Start recording your app (red button at top |
12 |
| - /// left) and then you should see timing information for every action sent to the store and every |
13 |
| - /// effect executed. |
14 |
| - /// |
15 |
| - /// Effect instrumentation can be particularly useful for inspecting the lifecycle of long-living |
16 |
| - /// effects. For example, if you start an effect (e.g. a location manager) in `onAppear` and |
17 |
| - /// forget to tear down the effect in `onDisappear`, it will clearly show in Instruments that the |
18 |
| - /// effect never completed. |
19 |
| - /// |
20 |
| - /// - Parameters: |
21 |
| - /// - prefix: A string to print at the beginning of the formatted message for the signpost. |
22 |
| - /// - log: An `OSLog` to use for signposts. |
23 |
| - /// - Returns: A reducer that has been enhanced with instrumentation. |
24 |
| - @available( |
25 |
| - iOS, |
26 |
| - deprecated: 9999.0, |
| 4 | +extension AnyReducer { |
| 5 | + /// Instruments the reducer with |
| 6 | + /// [signposts](https://developer.apple.com/documentation/os/logging/recording_performance_data). |
| 7 | + /// Each invocation of the reducer will be measured by an interval, and the lifecycle of its |
| 8 | + /// effects will be measured with interval and event signposts. |
| 9 | + /// |
| 10 | + /// To use, build your app for Instruments (⌘I), create a blank instrument, and then use the "+" |
| 11 | + /// icon at top right to add the signpost instrument. Start recording your app (red button at top |
| 12 | + /// left) and then you should see timing information for every action sent to the store and every |
| 13 | + /// effect executed. |
| 14 | + /// |
| 15 | + /// Effect instrumentation can be particularly useful for inspecting the lifecycle of long-living |
| 16 | + /// effects. For example, if you start an effect (e.g. a location manager) in `onAppear` and |
| 17 | + /// forget to tear down the effect in `onDisappear`, it will clearly show in Instruments that the |
| 18 | + /// effect never completed. |
| 19 | + /// |
| 20 | + /// - Parameters: |
| 21 | + /// - prefix: A string to print at the beginning of the formatted message for the signpost. |
| 22 | + /// - log: An `OSLog` to use for signposts. |
| 23 | + /// - Returns: A reducer that has been enhanced with instrumentation. |
| 24 | + @available( |
| 25 | + iOS, |
| 26 | + deprecated: 9999.0, |
27 | 27 | message:
|
28 | 28 | """
|
29 | 29 | This API has been soft-deprecated in favor of 'ReducerProtocol.signpost'. Read the migration guide for more information: https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/reducerprotocol
|
30 | 30 | """
|
31 |
| - ) |
32 |
| - @available( |
33 |
| - macOS, |
34 |
| - deprecated: 9999.0, |
| 31 | + ) |
| 32 | + @available( |
| 33 | + macOS, |
| 34 | + deprecated: 9999.0, |
35 | 35 | message:
|
36 | 36 | """
|
37 | 37 | This API has been soft-deprecated in favor of 'ReducerProtocol.signpost'. Read the migration guide for more information: https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/reducerprotocol
|
38 | 38 | """
|
39 |
| - ) |
40 |
| - @available( |
41 |
| - tvOS, |
42 |
| - deprecated: 9999.0, |
| 39 | + ) |
| 40 | + @available( |
| 41 | + tvOS, |
| 42 | + deprecated: 9999.0, |
43 | 43 | message:
|
44 | 44 | """
|
45 | 45 | This API has been soft-deprecated in favor of 'ReducerProtocol.signpost'. Read the migration guide for more information: https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/reducerprotocol
|
46 | 46 | """
|
47 |
| - ) |
48 |
| - @available( |
49 |
| - watchOS, |
50 |
| - deprecated: 9999.0, |
| 47 | + ) |
| 48 | + @available( |
| 49 | + watchOS, |
| 50 | + deprecated: 9999.0, |
51 | 51 | message:
|
52 | 52 | """
|
53 | 53 | This API has been soft-deprecated in favor of 'ReducerProtocol.signpost'. Read the migration guide for more information: https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/reducerprotocol
|
54 | 54 | """
|
| 55 | + ) |
| 56 | + public func signpost( |
| 57 | + _ prefix: String = "", |
| 58 | + log: OSLog = OSLog( |
| 59 | + subsystem: "co.pointfree.composable-architecture", |
| 60 | + category: "Reducer Instrumentation" |
55 | 61 | )
|
56 |
| - public func signpost( |
57 |
| - _ prefix: String = "", |
58 |
| - log: OSLog = OSLog( |
59 |
| - subsystem: "co.pointfree.composable-architecture", |
60 |
| - category: "Reducer Instrumentation" |
61 |
| - ) |
62 |
| - ) -> Self { |
63 |
| - guard log.signpostsEnabled else { return self } |
| 62 | + ) -> Self { |
| 63 | + guard log.signpostsEnabled else { return self } |
64 | 64 |
|
65 |
| - // NB: Prevent rendering as "N/A" in Instruments |
66 |
| - let zeroWidthSpace = "\u{200B}" |
| 65 | + // NB: Prevent rendering as "N/A" in Instruments |
| 66 | + let zeroWidthSpace = "\u{200B}" |
67 | 67 |
|
68 |
| - let prefix = prefix.isEmpty ? zeroWidthSpace : "[\(prefix)] " |
| 68 | + let prefix = prefix.isEmpty ? zeroWidthSpace : "[\(prefix)] " |
69 | 69 |
|
70 |
| - return Self { state, action, environment in |
71 |
| - var actionOutput: String! |
72 |
| - if log.signpostsEnabled { |
73 |
| - actionOutput = debugCaseOutput(action) |
74 |
| - os_signpost(.begin, log: log, name: "Action", "%s%s", prefix, actionOutput) |
75 |
| - } |
76 |
| - let effects = self.run(&state, action, environment) |
77 |
| - if log.signpostsEnabled { |
78 |
| - os_signpost(.end, log: log, name: "Action") |
79 |
| - return |
80 |
| - effects |
81 |
| - .effectSignpost(prefix, log: log, actionOutput: actionOutput) |
82 |
| - } |
83 |
| - return effects |
| 70 | + return Self { state, action, environment in |
| 71 | + var actionOutput: String! |
| 72 | + if log.signpostsEnabled { |
| 73 | + actionOutput = debugCaseOutput(action) |
| 74 | + os_signpost(.begin, log: log, name: "Action", "%s%s", prefix, actionOutput) |
84 | 75 | }
|
| 76 | + let effects = self.run(&state, action, environment) |
| 77 | + if log.signpostsEnabled { |
| 78 | + os_signpost(.end, log: log, name: "Action") |
| 79 | + return |
| 80 | + effects |
| 81 | + .effectSignpost(prefix, log: log, actionOutput: actionOutput) |
| 82 | + } |
| 83 | + return effects |
85 | 84 | }
|
86 | 85 | }
|
| 86 | +} |
87 | 87 |
|
88 |
| - extension Effect where Failure == Never { |
89 |
| - @usableFromInline |
90 |
| - func effectSignpost( |
91 |
| - _ prefix: String, |
92 |
| - log: OSLog, |
93 |
| - actionOutput: String |
94 |
| - ) -> Self { |
95 |
| - let sid = OSSignpostID(log: log) |
| 88 | +extension Effect where Failure == Never { |
| 89 | + @usableFromInline |
| 90 | + func effectSignpost( |
| 91 | + _ prefix: String, |
| 92 | + log: OSLog, |
| 93 | + actionOutput: String |
| 94 | + ) -> Self { |
| 95 | + let sid = OSSignpostID(log: log) |
96 | 96 |
|
97 |
| - switch self.operation { |
98 |
| - case .none: |
99 |
| - return self |
| 97 | + switch self.operation { |
| 98 | + case .none: |
| 99 | + return self |
100 | 100 | case let .producer(producer):
|
101 |
| - return .init( |
| 101 | + return .init( |
102 | 102 | operation: .producer(
|
103 | 103 | producer
|
104 | 104 | .on(
|
105 | 105 | starting: {
|
106 |
| - os_signpost( |
107 |
| - .begin, log: log, name: "Effect", signpostID: sid, "%sStarted from %s", prefix, |
| 106 | + os_signpost( |
| 107 | + .begin, log: log, name: "Effect", signpostID: sid, "%sStarted from %s", prefix, |
108 | 108 | actionOutput
|
109 | 109 | )
|
110 | 110 | },
|
111 | 111 | completed: {
|
112 | 112 | os_signpost(.end, log: log, name: "Effect", signpostID: sid, "%sFinished", prefix)
|
113 |
| - }, |
| 113 | + }, |
114 | 114 | disposed: {
|
115 |
| - os_signpost( |
| 115 | + os_signpost( |
116 | 116 | .end, log: log, name: "Effect", signpostID: sid, "%sCancelled", prefix)
|
117 |
| - }, |
| 117 | + }, |
118 | 118 | value: { value in
|
119 | 119 | os_signpost(
|
120 | 120 | .event, log: log, name: "Effect Output", "%sOutput from %s", prefix,
|
121 | 121 | actionOutput
|
122 | 122 | )
|
123 |
| - } |
124 |
| - ) |
| 123 | + } |
125 | 124 | )
|
126 | 125 | )
|
127 |
| - case let .run(priority, operation): |
128 |
| - return .init( |
129 |
| - operation: .run(priority) { send in |
130 |
| - os_signpost( |
131 |
| - .begin, log: log, name: "Effect", signpostID: sid, "%sStarted from %s", prefix, |
132 |
| - actionOutput |
133 |
| - ) |
134 |
| - await operation( |
135 |
| - Send { action in |
136 |
| - os_signpost( |
137 |
| - .event, log: log, name: "Effect Output", "%sOutput from %s", prefix, actionOutput |
138 |
| - ) |
139 |
| - send(action) |
140 |
| - } |
141 |
| - ) |
142 |
| - if Task.isCancelled { |
143 |
| - os_signpost(.end, log: log, name: "Effect", signpostID: sid, "%sCancelled", prefix) |
| 126 | + ) |
| 127 | + case let .run(priority, operation): |
| 128 | + return .init( |
| 129 | + operation: .run(priority) { send in |
| 130 | + os_signpost( |
| 131 | + .begin, log: log, name: "Effect", signpostID: sid, "%sStarted from %s", prefix, |
| 132 | + actionOutput |
| 133 | + ) |
| 134 | + await operation( |
| 135 | + Send { action in |
| 136 | + os_signpost( |
| 137 | + .event, log: log, name: "Effect Output", "%sOutput from %s", prefix, actionOutput |
| 138 | + ) |
| 139 | + send(action) |
144 | 140 | }
|
145 |
| - os_signpost(.end, log: log, name: "Effect", signpostID: sid, "%sFinished", prefix) |
| 141 | + ) |
| 142 | + if Task.isCancelled { |
| 143 | + os_signpost(.end, log: log, name: "Effect", signpostID: sid, "%sCancelled", prefix) |
146 | 144 | }
|
147 |
| - ) |
148 |
| - } |
| 145 | + os_signpost(.end, log: log, name: "Effect", signpostID: sid, "%sFinished", prefix) |
| 146 | + } |
| 147 | + ) |
149 | 148 | }
|
150 | 149 | }
|
| 150 | +} |
151 | 151 | #endif
|
152 | 152 |
|
153 | 153 | @usableFromInline
|
|
0 commit comments