org.zodiac.datasource.r2dbc.switcher.DefaultReactiveSwitcher Maven / Gradle / Ivy
package org.zodiac.datasource.r2dbc.switcher;
import org.reactivestreams.Publisher;
import org.zodiac.commons.context.ReactorContexts;
import org.zodiac.sdk.toolkit.context.ContextKey;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Collection;
import java.util.Deque;
import java.util.LinkedList;
import java.util.function.Consumer;
import java.util.function.Function;
public class DefaultReactiveSwitcher implements ReactiveSwitcher {
private String name;
private String defaultId;
private String type;
public DefaultReactiveSwitcher(String name, String type) {
this.name = "ReactiveSwitcher.".concat(name);
this.defaultId = name.concat(".").concat("_default");
this.type = type;
}
private Mono doInContext(Function, Mono> function) {
return ReactorContexts.reactiveContext()
.map(ctx -> ctx.getOrDefault(ContextKey.>of(this.name), LinkedList::new)).flatMap(function);
}
@SuppressWarnings("all")
private > R doInContext(R publisher, Consumer> consumer) {
if (publisher instanceof Mono) {
return (R)((Mono>)publisher).subscriberContext(ReactorContexts.acceptContext(ctx -> {
consumer.accept(ctx.getOrDefault(ContextKey.>of(this.name), LinkedList::new));
}));
} else if (publisher instanceof Flux) {
return (R)((Flux>)publisher).subscriberContext(ReactorContexts.acceptContext(ctx -> {
consumer.accept(ctx.getOrDefault(ContextKey.>of(this.name), LinkedList::new));
}));
}
return publisher;
}
@Override
public > P useLast(P publisher) {
return doInContext(publisher, queue -> {
/*没有上一次了*/
if (queue.isEmpty()) {
return;
}
/*移除队尾,则当前的队尾则为上一次使用的配置*/
queue.removeLast();
});
}
@Override
public
> P use(P publisher, String id) {
return doInContext(publisher, queue -> queue.addLast(id));
}
@Override
public
> P useDefault(P publisher) {
return use(publisher, defaultId);
}
@Override
public
> P reset(P publisher) {
return doInContext(publisher, Collection::clear);
}
@Override
public Mono current() {
return doInContext(queue -> {
if (queue.isEmpty()) {
return Mono.empty();
}
String activeId = queue.getLast();
if (defaultId.equals(activeId)) {
return Mono.empty();
}
return Mono.just(activeId);
});
}
}