Skip to content

Commit cc4335e

Browse files
committed
[ECO-5506] Declared separate interface ObjectsCallback for async ops
- Updated ObjectsAsyncScope to handle ObjectsCallback - Added launchWithVoidCallback method to handle void callbacks - Added unit tests covering all scenarios for ObjectsAsyncScope
1 parent 3f5d115 commit cc4335e

File tree

9 files changed

+359
-28
lines changed

9 files changed

+359
-28
lines changed

lib/src/main/java/io/ably/lib/objects/LiveCounter.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.ably.lib.objects;
22

3-
import io.ably.lib.types.Callback;
43
import org.jetbrains.annotations.Blocking;
54
import org.jetbrains.annotations.NonBlocking;
65
import org.jetbrains.annotations.NotNull;
@@ -33,7 +32,7 @@ public interface LiveCounter {
3332
* @param callback the callback to be invoked upon completion of the operation.
3433
*/
3534
@NonBlocking
36-
void incrementAsync(@NotNull Callback<Void> callback);
35+
void incrementAsync(@NotNull ObjectsCallback<Void> callback);
3736

3837
/**
3938
* Decrements the value of the counter by 1.
@@ -49,7 +48,7 @@ public interface LiveCounter {
4948
* @param callback the callback to be invoked upon completion of the operation.
5049
*/
5150
@NonBlocking
52-
void decrementAsync(@NotNull Callback<Void> callback);
51+
void decrementAsync(@NotNull ObjectsCallback<Void> callback);
5352

5453
/**
5554
* Retrieves the current value of the counter.

lib/src/main/java/io/ably/lib/objects/LiveMap.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.ably.lib.objects;
22

3-
import io.ably.lib.types.Callback;
43
import org.jetbrains.annotations.Blocking;
54
import org.jetbrains.annotations.NonBlocking;
65
import org.jetbrains.annotations.Contract;
@@ -109,7 +108,7 @@ public interface LiveMap {
109108
* @param callback the callback to handle the result or any errors.
110109
*/
111110
@NonBlocking
112-
void setAsync(@NotNull String keyName, @NotNull Object value, @NotNull Callback<Void> callback);
111+
void setAsync(@NotNull String keyName, @NotNull Object value, @NotNull ObjectsCallback<Void> callback);
113112

114113
/**
115114
* Asynchronously removes the specified key and its associated value from the map.
@@ -122,5 +121,5 @@ public interface LiveMap {
122121
* @param callback the callback to handle the result or any errors.
123122
*/
124123
@NonBlocking
125-
void removeAsync(@NotNull String keyName, @NotNull Callback<Void> callback);
124+
void removeAsync(@NotNull String keyName, @NotNull ObjectsCallback<Void> callback);
126125
}

lib/src/main/java/io/ably/lib/objects/LiveObjects.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.ably.lib.objects;
22

33
import io.ably.lib.objects.state.ObjectsStateChange;
4-
import io.ably.lib.types.Callback;
54
import org.jetbrains.annotations.Blocking;
65
import org.jetbrains.annotations.NonBlocking;
76
import org.jetbrains.annotations.NotNull;
@@ -96,7 +95,7 @@ public interface LiveObjects extends ObjectsStateChange {
9695
* @param callback the callback to handle the result or error.
9796
*/
9897
@NonBlocking
99-
void getRootAsync(@NotNull Callback<@NotNull LiveMap> callback);
98+
void getRootAsync(@NotNull ObjectsCallback<@NotNull LiveMap> callback);
10099

101100
/**
102101
* Asynchronously creates a new LiveMap based on an existing LiveMap.
@@ -109,7 +108,7 @@ public interface LiveObjects extends ObjectsStateChange {
109108
* @param callback the callback to handle the result or error.
110109
*/
111110
@NonBlocking
112-
void createMapAsync(@NotNull LiveMap liveMap, @NotNull Callback<@NotNull LiveMap> callback);
111+
void createMapAsync(@NotNull LiveMap liveMap, @NotNull ObjectsCallback<@NotNull LiveMap> callback);
113112

114113
/**
115114
* Asynchronously creates a new LiveMap based on a LiveCounter.
@@ -122,7 +121,7 @@ public interface LiveObjects extends ObjectsStateChange {
122121
* @param callback the callback to handle the result or error.
123122
*/
124123
@NonBlocking
125-
void createMapAsync(@NotNull LiveCounter liveCounter, @NotNull Callback<@NotNull LiveMap> callback);
124+
void createMapAsync(@NotNull LiveCounter liveCounter, @NotNull ObjectsCallback<@NotNull LiveMap> callback);
126125

127126
/**
128127
* Asynchronously creates a new LiveMap based on a standard Java Map.
@@ -135,7 +134,7 @@ public interface LiveObjects extends ObjectsStateChange {
135134
* @param callback the callback to handle the result or error.
136135
*/
137136
@NonBlocking
138-
void createMapAsync(@NotNull Map<String, Object> map, @NotNull Callback<@NotNull LiveMap> callback);
137+
void createMapAsync(@NotNull Map<String, Object> map, @NotNull ObjectsCallback<@NotNull LiveMap> callback);
139138

140139
/**
141140
* Asynchronously creates a new LiveCounter with an initial value.
@@ -148,5 +147,5 @@ public interface LiveObjects extends ObjectsStateChange {
148147
* @param callback the callback to handle the result or error.
149148
*/
150149
@NonBlocking
151-
void createCounterAsync(@NotNull Long initialValue, @NotNull Callback<@NotNull LiveCounter> callback);
150+
void createCounterAsync(@NotNull Long initialValue, @NotNull ObjectsCallback<@NotNull LiveCounter> callback);
152151
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.ably.lib.objects;
2+
3+
import io.ably.lib.types.AblyException;
4+
5+
/**
6+
* Callback interface for handling results of asynchronous LiveObjects operations.
7+
* Used for operations like creating LiveMaps/LiveCounters, modifying entries, and retrieving objects.
8+
* Callbacks are executed on background threads managed by the LiveObjects system.
9+
*
10+
* @param <T> the type of the result returned by the asynchronous operation
11+
*/
12+
public interface ObjectsCallback<T> {
13+
14+
/**
15+
* Called when the asynchronous operation completes successfully.
16+
* For modification operations (set, remove, increment), result is typically Void.
17+
* For creation/retrieval operations, result contains the created/retrieved object.
18+
*
19+
* @param result the result of the operation, may be null for modification operations
20+
*/
21+
void onSuccess(T result);
22+
23+
/**
24+
* Called when the asynchronous operation fails.
25+
* The exception contains detailed error information including error codes and messages.
26+
* Common errors include network issues, authentication failures, and validation errors.
27+
*
28+
* @param exception the exception that occurred during the operation
29+
*/
30+
void onError(AblyException exception);
31+
}

live-objects/src/main/kotlin/io/ably/lib/objects/DefaultLiveObjects.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import io.ably.lib.objects.state.ObjectsStateChange
44
import io.ably.lib.objects.state.ObjectsStateEvent
55
import io.ably.lib.realtime.ChannelState
66
import io.ably.lib.types.AblyException
7-
import io.ably.lib.types.Callback
87
import io.ably.lib.types.ProtocolMessage
98
import io.ably.lib.util.Log
109
import kotlinx.coroutines.*
@@ -66,23 +65,23 @@ internal class DefaultLiveObjects(internal val channelName: String, internal val
6665
TODO("Not yet implemented")
6766
}
6867

69-
override fun getRootAsync(callback: Callback<LiveMap>) {
68+
override fun getRootAsync(callback: ObjectsCallback<LiveMap>) {
7069
asyncScope.launchWithCallback(callback) { getRootAsync() }
7170
}
7271

73-
override fun createMapAsync(liveMap: LiveMap, callback: Callback<LiveMap>) {
72+
override fun createMapAsync(liveMap: LiveMap, callback: ObjectsCallback<LiveMap>) {
7473
TODO("Not yet implemented")
7574
}
7675

77-
override fun createMapAsync(liveCounter: LiveCounter, callback: Callback<LiveMap>) {
76+
override fun createMapAsync(liveCounter: LiveCounter, callback: ObjectsCallback<LiveMap>) {
7877
TODO("Not yet implemented")
7978
}
8079

81-
override fun createMapAsync(map: MutableMap<String, Any>, callback: Callback<LiveMap>) {
80+
override fun createMapAsync(map: MutableMap<String, Any>, callback: ObjectsCallback<LiveMap>) {
8281
TODO("Not yet implemented")
8382
}
8483

85-
override fun createCounterAsync(initialValue: Long, callback: Callback<LiveCounter>) {
84+
override fun createCounterAsync(initialValue: Long, callback: ObjectsCallback<LiveCounter>) {
8685
TODO("Not yet implemented")
8786
}
8887

live-objects/src/main/kotlin/io/ably/lib/objects/Utils.kt

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.ably.lib.objects
22

33
import io.ably.lib.types.AblyException
4-
import io.ably.lib.types.Callback
54
import io.ably.lib.types.ErrorInfo
65
import io.ably.lib.util.Log
76
import kotlinx.coroutines.*
@@ -60,16 +59,40 @@ internal class ObjectsAsyncScope(channelName: String) {
6059
private val scope =
6160
CoroutineScope(Dispatchers.Default + CoroutineName(tag) + SupervisorJob())
6261

63-
internal fun <T> launchWithCallback(callback: Callback<T>, block: suspend () -> T) {
62+
internal fun <T> launchWithCallback(callback: ObjectsCallback<T>, block: suspend () -> T) {
6463
scope.launch {
6564
try {
6665
val result = block()
6766
try { callback.onSuccess(result) } catch (t: Throwable) {
6867
Log.e(tag, "Error occurred while executing callback's onSuccess handler", t)
6968
} // catch and don't rethrow error from callback
7069
} catch (throwable: Throwable) {
71-
val exception = throwable as? AblyException
72-
callback.onError(exception?.errorInfo)
70+
when (throwable) {
71+
is AblyException -> { callback.onError(throwable) }
72+
else -> {
73+
val ex = ablyException("Error executing operation", ErrorCode.BadRequest, cause = throwable)
74+
callback.onError(ex)
75+
}
76+
}
77+
}
78+
}
79+
}
80+
81+
internal fun launchWithVoidCallback(callback: ObjectsCallback<Void>, block: suspend () -> Unit) {
82+
scope.launch {
83+
try {
84+
block()
85+
try { callback.onSuccess(null) } catch (t: Throwable) {
86+
Log.e(tag, "Error occurred while executing callback's onSuccess handler", t)
87+
} // catch and don't rethrow error from callback
88+
} catch (throwable: Throwable) {
89+
when (throwable) {
90+
is AblyException -> { callback.onError(throwable) }
91+
else -> {
92+
val ex = ablyException("Error executing operation", ErrorCode.BadRequest, cause = throwable)
93+
callback.onError(ex)
94+
}
95+
}
7396
}
7497
}
7598
}

live-objects/src/main/kotlin/io/ably/lib/objects/type/livecounter/DefaultLiveCounter.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import io.ably.lib.objects.ObjectOperation
55
import io.ably.lib.objects.ObjectState
66
import io.ably.lib.objects.type.BaseLiveObject
77
import io.ably.lib.objects.type.ObjectType
8-
import io.ably.lib.types.Callback
98
import java.util.concurrent.atomic.AtomicReference
109

1110
/**
@@ -38,15 +37,15 @@ internal class DefaultLiveCounter private constructor(
3837
TODO("Not yet implemented")
3938
}
4039

41-
override fun incrementAsync(callback: Callback<Void>) {
40+
override fun incrementAsync(callback: ObjectsCallback<Void>) {
4241
TODO("Not yet implemented")
4342
}
4443

4544
override fun decrement() {
4645
TODO("Not yet implemented")
4746
}
4847

49-
override fun decrementAsync(callback: Callback<Void>) {
48+
override fun decrementAsync(callback: ObjectsCallback<Void>) {
5049
TODO("Not yet implemented")
5150
}
5251

live-objects/src/main/kotlin/io/ably/lib/objects/type/livemap/DefaultLiveMap.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import io.ably.lib.objects.ObjectOperation
77
import io.ably.lib.objects.ObjectState
88
import io.ably.lib.objects.type.BaseLiveObject
99
import io.ably.lib.objects.type.ObjectType
10-
import io.ably.lib.types.Callback
1110
import java.util.concurrent.ConcurrentHashMap
1211
import java.util.AbstractMap
1312

@@ -94,11 +93,11 @@ internal class DefaultLiveMap private constructor(
9493
TODO("Not yet implemented")
9594
}
9695

97-
override fun setAsync(keyName: String, value: Any, callback: Callback<Void>) {
96+
override fun setAsync(keyName: String, value: Any, callback: ObjectsCallback<Void>) {
9897
TODO("Not yet implemented")
9998
}
10099

101-
override fun removeAsync(keyName: String, callback: Callback<Void>) {
100+
override fun removeAsync(keyName: String, callback: ObjectsCallback<Void>) {
102101
TODO("Not yet implemented")
103102
}
104103

0 commit comments

Comments
 (0)