Add os_signpost logs for render() and Workflow and Worker lifecycle
ADD
swift/Workflow/Sources/Log.swift
+/*
+ * Copyright 2020 Square Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import os.signpost
+
+extension OSLog {
+ static let workflow = OSLog(subsystem: "com.squareup.Workflow", category: "Workflow")
+ static let worker = OSLog(subsystem: "com.squareup.Workflow", category: "Worker")
+}

MODIFY
swift/Workflow/Sources/SubtreeManager.swift
swift/Workflow/Sources/SubtreeManager.swift
import Dispatch
import ReactiveSwift
+import os.signpost
extension WorkflowNode {
/// Manages the subtree of a workflow. Specifically, this type encapsulates the logic required to update and manage
@@ -204,7 +205,14 @@ extension WorkflowNode.SubtreeManager {
func makeSink<Action>(of actionType: Action.Type) -> Sink<Action> where Action: WorkflowAction, WorkflowType == Action.WorkflowType {
let reusableSink = sinkStore.findOrCreate(actionType: Action.self)
+ let signpostRef = NSObject()
+
let sink = Sink<Action> { action in
+ if #available(iOS 12.0, *) {
+ let signpostID = OSSignpostID(log: .workflow, object: signpostRef)
+ os_signpost(.event, log: .workflow, name: "Sink Event", signpostID: signpostID, "Event: %@", String(describing: action))
+ }
+
reusableSink.handle(action: action)
}
@@ -407,11 +415,36 @@ extension WorkflowNode.SubtreeManager {
self.outputMap = outputMap
super.init(eventPipe: eventPipe)
+ let signpostRef = NSObject()
+
+ if #available(iOS 12.0, *) {
+ let signpostID = OSSignpostID(log: .worker, object: signpostRef)
+ os_signpost(.begin, log: .worker, name: "Worker Created", signpostID: signpostID, "Worker: %{public}@", String(describing: W.self))
+ }
+
signalProducer
.take(during: lifetime)
.observe(on: QueueScheduler.workflowExecution)
- .startWithValues { [weak self] output in
+ .start { [weak self] event in
+ switch event {
+ case .value(let output):
self?.handle(output: output)
+ case .completed:
+ if #available(iOS 12.0, *) {
+ let signpostID = OSSignpostID(log: .worker, object: signpostRef)
+ os_signpost(.end, log: .worker, name: "Worker Created", signpostID: signpostID)
+ }
+ case .interrupted:
+ if #available(iOS 12.0, *) {
+ let signpostID = OSSignpostID(log: .worker, object: signpostRef)
+ os_signpost(.end, log: .worker, name: "Worker Created", signpostID: signpostID, "Interrupted")
+ }
+ case .failed:
+ if #available(iOS 12.0, *) {
+ let signpostID = OSSignpostID(log: .worker, object: signpostRef)
+ os_signpost(.end, log: .worker, name: "Worker Created", signpostID: signpostID, "Failed")
+ }
+ }
}
}

MODIFY
swift/Workflow/Sources/WorkflowNode.swift
swift/Workflow/Sources/WorkflowNode.swift
*/
import ReactiveSwift
+import os.signpost
/// Manages a running workflow.
final class WorkflowNode<WorkflowType: Workflow> {
@@ -34,11 +35,23 @@ final class WorkflowNode<WorkflowType: Workflow> {
self.workflow = workflow
self.state = workflow.makeInitialState()
+ if #available(iOS 12.0, *) {
+ let signpostID = OSSignpostID(log: .workflow, object: self)
+ os_signpost(.begin, log: .workflow, name: "Alive", signpostID: signpostID, "Workflow: %{public}@", String(describing: WorkflowType.self))
+ }
+
subtreeManager.onUpdate = { [weak self] output in
self?.handle(subtreeOutput: output)
}
}
+ deinit {
+ if #available(iOS 12.0, *) {
+ let signpostID = OSSignpostID(log: .workflow, object: self)
+ os_signpost(.end, log: .workflow, name: "Alive", signpostID: signpostID)
+ }
+ }
+
/// Handles an event produced by the subtree manager
private func handle(subtreeOutput: SubtreeManager.Output) {
let output: Output
@@ -71,6 +84,18 @@ final class WorkflowNode<WorkflowType: Workflow> {
}
func render() -> WorkflowType.Rendering {
+ if #available(iOS 12.0, *) {
+ let signpostID = OSSignpostID(log: .workflow, object: self)
+ os_signpost(.begin, log: .workflow, name: "Render", signpostID: signpostID, "Render Workflow: %{public}@", String(describing: WorkflowType.self))
+ }
+
+ defer {
+ if #available(iOS 12.0, *) {
+ let signpostID = OSSignpostID(log: .workflow, object: self)
+ os_signpost(.end, log: .workflow, name: "Render", signpostID: signpostID)
+ }
+ }
+
return subtreeManager.render { context in
workflow
.render(

Add os_signpost logs for render() and Workflow and Worker lifecycle