package netflix.ocelli.client;
import netflix.ocelli.util.RxUtil;
import rx.Observable;
import rx.Scheduler;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class Behaviors {
public static Func1<TestClient, Observable<TestClient>> delay(final long amount, final TimeUnit units) {
return delay(amount, units, Schedulers.computation());
}
public static Func1<TestClient, Observable<TestClient>> delay(final long amount, final TimeUnit units, final Scheduler scheduler) {
return new Func1<TestClient, Observable<TestClient>>() {
@Override
public Observable<TestClient> call(final TestClient client) {
return Observable
.just(client)
.delay(amount, units, scheduler)
;
}
};
}
public static Func1<TestClient, Observable<TestClient>> immediate() {
return new Func1<TestClient, Observable<TestClient>>() {
@Override
public Observable<TestClient> call(TestClient client) {
return Observable
.just(client);
}
};
}
public static Func1<TestClient, Observable<TestClient>> failure(final long amount, final TimeUnit units) {
return failure(amount, units, Schedulers.computation());
}
public static Func1<TestClient, Observable<TestClient>> failure(final long amount, final TimeUnit units, final Scheduler scheduler) {
return new Func1<TestClient, Observable<TestClient>>() {
@Override
public Observable<TestClient> call(TestClient client) {
return Observable.timer(amount, units, scheduler)
.flatMap(new Func1<Long, Observable<TestClient>>() {
@Override
public Observable<TestClient> call(Long t1) {
return Observable.error(new Exception("SimulatedErrorBehavior"));
}
});
}
};
}
public static Func1<TestClient, Observable<TestClient>> failFirst(final int num) {
return new Func1<TestClient, Observable<TestClient>>() {
private int counter;
@Override
public Observable<TestClient> call(TestClient client) {
if (counter++ < num) {
return Observable.error(new Exception("Failure-" + counter));
}
return Observable.just(client);
}
};
}
public static Func1<TestClient, Observable<TestClient>> failure() {
return new Func1<TestClient, Observable<TestClient>>() {
@Override
public Observable<TestClient> call(TestClient client) {
return Observable
.just(client)
.concatWith(Observable.<TestClient>error(new Exception("SimulatedErrorBehavior")));
}
};
}
public static Func1<TestClient, Observable<TestClient>> degradation(final long initial, final long step, final TimeUnit units) {
return new Func1<TestClient, Observable<TestClient>>() {
private AtomicLong counter = new AtomicLong(0);
@Override
public Observable<TestClient> call(TestClient client) {
return Observable
.just(client)
.delay(initial + counter.incrementAndGet() + step, units);
}
};
}
public static Func1<TestClient, Observable<TestClient>> proportionalToLoad(final long baseline, final long step, final TimeUnit units) {
return new Func1<TestClient, Observable<TestClient>>() {
private AtomicLong counter = new AtomicLong(0);
@Override
public Observable<TestClient> call(TestClient client) {
final long count = counter.incrementAndGet();
return Observable
.just(client)
.delay(baseline + count + step, units)
.finallyDo(RxUtil.decrement(counter));
}
};
}
public static Func1<TestClient, Observable<TestClient>> empty() {
return new Func1<TestClient, Observable<TestClient>>() {
@Override
public Observable<TestClient> call(TestClient t1) {
return Observable.empty();
}
};
}
// public static poissonDelay()
// public static gaussianDelay();
// public static gcPauses();
}