@ -15,21 +15,25 @@
* /
package org.redisson ;
import org.redisson.api.RFuture ;
import org.redisson.connection.ServiceManager ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import java.util.Map ;
import java.util.concurrent.CompletableFuture ;
import java.util.concurrent.CompletionStage ;
import java.util.concurrent.ConcurrentHashMap ;
import java.util.concurrent.TimeUnit ;
import java.util.function.Consumer ;
import java.util.function.Function ;
import java.util.function.Supplier ;
/ * *
* @author Nikita Koksharov
* /
public class ElementsSubscribeService {
private static final Logger log = LoggerFactory . getLogger ( ElementsSubscribeService . class ) ;
private final Map < Integer , CompletableFuture < ? > > subscribeListeners = new ConcurrentHashMap < > ( ) ;
private final ServiceManager serviceManager ;
@ -37,7 +41,17 @@ public class ElementsSubscribeService {
this . serviceManager = serviceManager ;
}
public < V > int subscribeOnElements ( Supplier < RFuture < V > > func , Consumer < V > consumer ) {
public < V > int subscribeOnElements ( Supplier < CompletionStage < V > > func , Function < V , CompletionStage < Void > > consumer ) {
int id = System . identityHashCode ( consumer ) ;
CompletableFuture < ? > currentFuture = subscribeListeners . putIfAbsent ( id , CompletableFuture . completedFuture ( null ) ) ;
if ( currentFuture ! = null ) {
throw new IllegalArgumentException ( "Consumer object with listener id " + id + " already registered" ) ;
}
resubscribe ( func , consumer ) ;
return id ;
}
public < V > int subscribeOnElements ( Supplier < CompletionStage < V > > func , Consumer < V > consumer ) {
int id = System . identityHashCode ( consumer ) ;
CompletableFuture < ? > currentFuture = subscribeListeners . putIfAbsent ( id , CompletableFuture . completedFuture ( null ) ) ;
if ( currentFuture ! = null ) {
@ -54,9 +68,9 @@ public class ElementsSubscribeService {
}
}
private < V > void resubscribe ( Supplier < RFutur e< V > > func , Consumer < V > consumer ) {
private < V > void resubscribe ( Supplier < CompletionStag e< V > > func , Consumer < V > consumer ) {
int listenerId = System . identityHashCode ( consumer ) ;
Complet ableFuture< V > f = ( CompletableFutur e< V > ) subscribeListeners . computeIfPresent ( listenerId , ( k , v ) - > {
Complet ionStage< V > f = ( CompletionStag e< V > ) subscribeListeners . computeIfPresent ( listenerId , ( k , v ) - > {
return func . get ( ) . toCompletableFuture ( ) ;
} ) ;
if ( f = = null ) {
@ -76,5 +90,27 @@ public class ElementsSubscribeService {
} ) ;
}
private < V > void resubscribe ( Supplier < CompletionStage < V > > func , Function < V , CompletionStage < Void > > consumer ) {
int listenerId = System . identityHashCode ( consumer ) ;
CompletionStage < V > f = ( CompletionStage < V > ) subscribeListeners . computeIfPresent ( listenerId , ( k , v ) - > {
return func . get ( ) . toCompletableFuture ( ) ;
} ) ;
if ( f = = null ) {
return ;
}
f . thenCompose ( consumer ) . whenComplete ( ( r , ex ) - > {
if ( ex ! = null ) {
log . error ( ex . getMessage ( ) , ex ) ;
serviceManager . newTimeout ( t - > {
resubscribe ( func , consumer ) ;
} , 1 , TimeUnit . SECONDS ) ;
return ;
}
resubscribe ( func , consumer ) ;
} ) ;
}
}