Skip to content

Commit 43423f8

Browse files
authored
Added some documentations to AsyncLock file (#2627)
1 parent ef1d4de commit 43423f8

File tree

2 files changed

+196
-11
lines changed

2 files changed

+196
-11
lines changed

RxSwift/Concurrency/AsyncLock.swift

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,58 @@ final class AsyncLock<I: InvocableType>
2929
private var isExecuting: Bool = false
3030
private var hasFaulted: Bool = false
3131

32-
// lock {
32+
/**
33+
Locks the current instance, preventing other threads from modifying it until `unlock()` is called.
34+
35+
This method is used to create a critical section where only one thread is allowed to access the protected resources at a time.
36+
37+
Example usage:
38+
```swift
39+
let lock = AsyncLock<SomeAction>()
40+
lock.lock()
41+
// Critical section
42+
lock.unlock()
43+
```
44+
*/
3345
func lock() {
3446
self._lock.lock()
3547
}
3648

49+
/**
50+
Unlocks the current instance, allowing other threads to access the protected resources.
51+
52+
This method is called after a `lock()` to release the critical section, ensuring that other waiting threads can proceed.
53+
54+
Example usage:
55+
```swift
56+
let lock = AsyncLock<SomeAction>()
57+
lock.lock()
58+
// Critical section
59+
lock.unlock()
60+
```
61+
*/
3762
func unlock() {
3863
self._lock.unlock()
3964
}
40-
// }
65+
66+
// MARK: - Queue Methods
4167

68+
/**
69+
Enqueues an action into the internal queue for deferred execution.
70+
71+
If no actions are currently being executed, the method returns the action for immediate execution. Otherwise, the action is enqueued for deferred execution when the lock is available.
72+
73+
- Parameter action: The action to enqueue.
74+
- Returns: The action if it can be executed immediately, or `nil` if it has been enqueued.
75+
76+
Example usage:
77+
```swift
78+
let lock = AsyncLock<SomeAction>()
79+
if let action = lock.enqueue(someAction) {
80+
action.invoke() // Execute the action immediately if it's not deferred.
81+
}
82+
```
83+
*/
4284
private func enqueue(_ action: I) -> I? {
4385
self.lock(); defer { self.unlock() }
4486
if self.hasFaulted {
@@ -55,6 +97,19 @@ final class AsyncLock<I: InvocableType>
5597
return action
5698
}
5799

100+
/**
101+
Dequeues the next action for execution, if available.
102+
103+
If the queue is empty, this method resets the `isExecuting` flag to indicate that no actions are currently being executed.
104+
105+
- Returns: The next action from the queue, or `nil` if the queue is empty.
106+
107+
Example usage:
108+
```swift
109+
let nextAction = lock.dequeue()
110+
nextAction?.invoke() // Execute the next action if one is available.
111+
```
112+
*/
58113
private func dequeue() -> I? {
59114
self.lock(); defer { self.unlock() }
60115
if !self.queue.isEmpty {
@@ -66,6 +121,19 @@ final class AsyncLock<I: InvocableType>
66121
}
67122
}
68123

124+
/**
125+
Invokes the provided action, ensuring that actions are executed sequentially.
126+
127+
The first action is executed immediately if no other actions are currently running. If other actions are already in the queue, the new action is enqueued and executed sequentially after the current actions are completed.
128+
129+
- Parameter action: The action to be invoked.
130+
131+
Example usage:
132+
```swift
133+
let lock = AsyncLock<SomeAction>()
134+
lock.invoke(someAction) // Invoke or enqueue the action.
135+
```
136+
*/
69137
func invoke(_ action: I) {
70138
let firstEnqueuedAction = self.enqueue(action)
71139

@@ -88,11 +156,34 @@ final class AsyncLock<I: InvocableType>
88156
}
89157
}
90158
}
91-
159+
160+
// MARK: - Dispose Methods
161+
162+
/**
163+
Disposes of the `AsyncLock` by clearing the internal queue and preventing further actions from being executed.
164+
165+
This method ensures that all pending actions are discarded, and the lock enters a faulted state where no new actions can be enqueued or executed.
166+
167+
Example usage:
168+
```swift
169+
let lock = AsyncLock<SomeAction>()
170+
lock.dispose() // Clear the queue and prevent further actions.
171+
```
172+
*/
92173
func dispose() {
93174
self.synchronizedDispose()
94175
}
95176

177+
/**
178+
Synchronously disposes of the internal queue and marks the lock as faulted.
179+
180+
This method is typically used internally to handle disposal of the lock in a thread-safe manner.
181+
182+
Example usage:
183+
```swift
184+
lock.synchronized_dispose()
185+
```
186+
*/
96187
func synchronized_dispose() {
97188
self.queue = Queue(capacity: 0)
98189
self.hasFaulted = true

RxSwift/GroupedObservable.swift

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,124 @@
66
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
77
//
88

9-
/// Represents an observable sequence of elements that have a common key.
9+
/// Represents an observable sequence of elements that share a common key.
10+
/// `GroupedObservable` is typically created by the `groupBy` operator.
11+
/// Each `GroupedObservable` instance represents a collection of elements
12+
/// that are grouped by a specific key.
13+
///
14+
/// Example usage:
15+
/// ```
16+
/// let observable = Observable.of("Apple", "Banana", "Apricot", "Blueberry", "Avocado")
17+
///
18+
/// let grouped = observable.groupBy { fruit in
19+
/// fruit.first! // Grouping by the first letter of each fruit
20+
/// }
21+
///
22+
/// _ = grouped.subscribe { group in
23+
/// print("Group: \(group.key)")
24+
/// _ = group.subscribe { event in
25+
/// print(event)
26+
/// }
27+
/// }
28+
/// ```
29+
/// This will print:
30+
/// ```
31+
/// Group: A
32+
/// next(Apple)
33+
/// next(Apricot)
34+
/// next(Avocado)
35+
/// Group: B
36+
/// next(Banana)
37+
/// next(Blueberry)
38+
/// ```
1039
public struct GroupedObservable<Key, Element> : ObservableType {
11-
/// Gets the common key.
40+
/// The key associated with this grouped observable sequence.
41+
/// All elements emitted by this observable share this common key.
1242
public let key: Key
1343

1444
private let source: Observable<Element>
1545

16-
/// Initializes grouped observable sequence with key and source observable sequence.
46+
/// Initializes a grouped observable sequence with a key and a source observable sequence.
1747
///
18-
/// - parameter key: Grouped observable sequence key
19-
/// - parameter source: Observable sequence that represents sequence of elements for the key
20-
/// - returns: Grouped observable sequence of elements for the specific key
48+
/// - Parameters:
49+
/// - key: The key associated with this grouped observable sequence.
50+
/// - source: The observable sequence of elements for the specified key.
51+
///
52+
/// Example usage:
53+
/// ```
54+
/// let sourceObservable = Observable.of("Apple", "Apricot", "Avocado")
55+
/// let groupedObservable = GroupedObservable(key: "A", source: sourceObservable)
56+
///
57+
/// _ = groupedObservable.subscribe { event in
58+
/// print(event)
59+
/// }
60+
/// ```
61+
/// This will print:
62+
/// ```
63+
/// next(Apple)
64+
/// next(Apricot)
65+
/// next(Avocado)
66+
/// ```
2167
public init(key: Key, source: Observable<Element>) {
2268
self.key = key
2369
self.source = source
2470
}
2571

26-
/// Subscribes `observer` to receive events for this sequence.
72+
/// Subscribes an observer to receive events emitted by the source observable sequence.
73+
///
74+
/// - Parameter observer: The observer that will receive the events of the source observable.
75+
/// - Returns: A `Disposable` representing the subscription, which can be used to cancel the subscription.
76+
///
77+
/// Example usage:
78+
/// ```
79+
/// let fruitsObservable = Observable.of("Apple", "Banana", "Apricot", "Blueberry", "Avocado")
80+
/// let grouped = fruitsObservable.groupBy { $0.first! } // Group by first letter
81+
///
82+
/// _ = grouped.subscribe { group in
83+
/// if group.key == "A" {
84+
/// _ = group.subscribe { event in
85+
/// print(event)
86+
/// }
87+
/// }
88+
/// }
89+
/// ```
90+
/// This will print:
91+
/// ```
92+
/// next(Apple)
93+
/// next(Apricot)
94+
/// next(Avocado)
95+
/// ```
2796
public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
2897
self.source.subscribe(observer)
2998
}
3099

31-
/// Converts `self` to `Observable` sequence.
100+
/// Converts this `GroupedObservable` into a regular `Observable` sequence.
101+
/// This allows you to work with the sequence without directly interacting with the key.
102+
///
103+
/// - Returns: The underlying `Observable` sequence of elements for the specified key.
104+
///
105+
/// Example usage:
106+
/// ```
107+
/// let fruitsObservable = Observable.of("Apple", "Banana", "Apricot", "Blueberry", "Avocado")
108+
/// let grouped = fruitsObservable.groupBy { $0.first! } // Group by first letter
109+
///
110+
/// _ = grouped.subscribe { group in
111+
/// if group.key == "A" {
112+
/// let regularObservable = group.asObservable()
113+
/// _ = regularObservable.subscribe { event in
114+
/// print(event)
115+
/// }
116+
/// }
117+
/// }
118+
/// ```
119+
/// This will print:
120+
/// ```
121+
/// next(Apple)
122+
/// next(Apricot)
123+
/// next(Avocado)
124+
/// ```
32125
public func asObservable() -> Observable<Element> {
33126
self.source
34127
}
35128
}
129+

0 commit comments

Comments
 (0)