Skip to content

Commit

Permalink
Merge pull request #236 from davidstump/feature/thread-safe-bindings
Browse files Browse the repository at this point in the history
Using SynchronizedArray to achieve threadsafe access to bindingsDel
  • Loading branch information
dsrees authored Apr 12, 2023
2 parents 0a1fddd + 8fcd2f9 commit 5aa9ac6
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 7 deletions.
4 changes: 2 additions & 2 deletions Examples/Basic/chatroom/ChatRoomViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ class ChatRoomViewController: UIViewController {

// MARK: - Attributes
private let username: String = "ChatRoom"
private let socket = Socket("http://localhost:4000/socket/websocket")
// private let socket = Socket("https://phxchat.herokuapp.com/socket/websocket")
// private let socket = Socket("http://localhost:4000/socket/websocket")
private let socket = Socket("https://phoenix-chat.fly.dev/socket/websocket")
private let topic: String = "room:lobby"

private var lobbyChannel: Channel?
Expand Down
10 changes: 5 additions & 5 deletions Sources/SwiftPhoenixClient/Channel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public class Channel {
var state: ChannelState

/// Collection of event bindings
var bindingsDel: [Binding]
var syncBindingsDel: SynchronizedArray<Binding>

/// Tracks event binding ref counters
var bindingRef: Int
Expand Down Expand Up @@ -108,7 +108,7 @@ public class Channel {
self.topic = topic
self.params = params
self.socket = socket
self.bindingsDel = []
self.syncBindingsDel = SynchronizedArray()
self.bindingRef = 0
self.timeout = socket.timeout
self.joinedOnce = false
Expand Down Expand Up @@ -405,7 +405,7 @@ public class Channel {
let ref = bindingRef
self.bindingRef = ref + 1

self.bindingsDel.append(Binding(event: event, ref: ref, callback: delegated))
self.syncBindingsDel.append(Binding(event: event, ref: ref, callback: delegated))
return ref
}

Expand All @@ -429,7 +429,7 @@ public class Channel {
/// - parameter event: Event to unsubscribe from
/// - paramter ref: Ref counter returned when subscribing. Can be omitted
public func off(_ event: String, ref: Int? = nil) {
self.bindingsDel.removeAll { (bind) -> Bool in
self.syncBindingsDel.removeAll { (bind) -> Bool in
bind.event == event && (ref == nil || ref == bind.ref)
}
}
Expand Down Expand Up @@ -572,7 +572,7 @@ public class Channel {
func trigger(_ message: Message) {
let handledMessage = self.onMessage(message)

self.bindingsDel
self.syncBindingsDel
.filter( { return $0.event == message.event } )
.forEach( { $0.callback.call(handledMessage) } )
}
Expand Down
35 changes: 35 additions & 0 deletions Sources/SwiftPhoenixClient/SynchronizedArray.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// SynchronizedArray.swift
// SwiftPhoenixClient
//
// Created by Daniel Rees on 4/12/23.
// Copyright © 2023 SwiftPhoenixClient. All rights reserved.
//

import Foundation

/// A thread-safe array.
public class SynchronizedArray<Element> {
fileprivate let queue = DispatchQueue(label: "spc_sync_array", attributes: .concurrent)
fileprivate var array = [Element]()

func append( _ newElement: Element) {
queue.async(flags: .barrier) {
self.array.append(newElement)
}
}

func removeAll(where shouldBeRemoved: @escaping (Element) -> Bool) {
queue.async(flags: .barrier) {
self.array.removeAll(where: shouldBeRemoved)
}
}

func filter(_ isIncluded: (Element) -> Bool) -> [Element] {
var result = [Element]()
queue.sync { result = self.array.filter(isIncluded) }
return result
}
}


4 changes: 4 additions & 0 deletions SwiftPhoenixClient.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
63B526DF2656D53700289719 /* Quick.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63B526DD2656D53700289719 /* Quick.xcframework */; };
63DE6CCA272A2ECB00E2A728 /* MessageSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DE6CC9272A2ECB00E2A728 /* MessageSpec.swift */; };
63F0F58D2592E44800C904FB /* ChatRoomViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63F0F58C2592E44800C904FB /* ChatRoomViewController.swift */; };
63F3765329E7296F00A5AB6E /* SynchronizedArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63F3765229E7296F00A5AB6E /* SynchronizedArray.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -117,6 +118,7 @@
63B526DD2656D53700289719 /* Quick.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Quick.xcframework; path = Carthage/Build/Quick.xcframework; sourceTree = "<group>"; };
63DE6CC9272A2ECB00E2A728 /* MessageSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSpec.swift; sourceTree = "<group>"; };
63F0F58C2592E44800C904FB /* ChatRoomViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatRoomViewController.swift; sourceTree = "<group>"; };
63F3765229E7296F00A5AB6E /* SynchronizedArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SynchronizedArray.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -206,6 +208,7 @@
12922E1F2543B10B0034B257 /* Socket.swift */,
12991E00254C3F1300BB8650 /* TimeoutTimer.swift */,
12922E212543B37B0034B257 /* PhoenixTransport.swift */,
63F3765229E7296F00A5AB6E /* SynchronizedArray.swift */,
);
path = SwiftPhoenixClient;
sourceTree = "<group>";
Expand Down Expand Up @@ -463,6 +466,7 @@
files = (
12991DFB254C3EB800BB8650 /* Defaults.swift in Sources */,
12991E05254C3F3300BB8650 /* Channel.swift in Sources */,
63F3765329E7296F00A5AB6E /* SynchronizedArray.swift in Sources */,
12991E09254C3F5B00BB8650 /* Presence.swift in Sources */,
12991E01254C3F1300BB8650 /* TimeoutTimer.swift in Sources */,
12991E07254C3F4B00BB8650 /* Message.swift in Sources */,
Expand Down

0 comments on commit 5aa9ac6

Please sign in to comment.