com.cmonbaby.http.rxjava.CallArbiter Maven / Gradle / Ivy
Show all versions of http_lower Show documentation
package com.cmonbaby.http.rxjava;
import java.util.concurrent.atomic.AtomicInteger;
import retrofit2.Call;
import retrofit2.Response;
import rx.Producer;
import rx.Subscriber;
import rx.Subscription;
import rx.exceptions.Exceptions;
import rx.exceptions.OnCompletedFailedException;
import rx.exceptions.OnErrorFailedException;
import rx.exceptions.OnErrorNotImplementedException;
/**
* Author: Simon
*
QO: 8950764
*
Email: [email protected]
*
WebSize: https://www.cmonbaby.com
*
Version: 1.0.0
*
Date: 2020/12/28
*
Description:
*/
final class CallArbiter extends AtomicInteger implements Subscription, Producer {
private static final int STATE_WAITING = 0;
private static final int STATE_REQUESTED = 1;
private static final int STATE_HAS_RESPONSE = 2;
private static final int STATE_TERMINATED = 3;
private final Call call;
private final Subscriber super Response> subscriber;
private volatile boolean unsubscribed;
private volatile Response response;
CallArbiter(Call call, Subscriber super Response> subscriber) {
super(STATE_WAITING);
this.call = call;
this.subscriber = subscriber;
}
@Override
public void unsubscribe() {
unsubscribed = true;
call.cancel();
}
@Override
public boolean isUnsubscribed() {
return unsubscribed;
}
@Override
public void request(long amount) {
if (amount == 0) {
return;
}
while (true) {
int state = get();
switch (state) {
case STATE_WAITING:
if (compareAndSet(STATE_WAITING, STATE_REQUESTED)) {
return;
}
break; // State transition failed. Try again.
case STATE_HAS_RESPONSE:
if (compareAndSet(STATE_HAS_RESPONSE, STATE_TERMINATED)) {
deliverResponse(response);
return;
}
break; // State transition failed. Try again.
case STATE_REQUESTED:
case STATE_TERMINATED:
return; // Nothing to do.
default:
throw new IllegalStateException("Unknown state: " + state);
}
}
}
void emitResponse(Response response) {
while (true) {
int state = get();
switch (state) {
case STATE_WAITING:
this.response = response;
if (compareAndSet(STATE_WAITING, STATE_HAS_RESPONSE)) {
return;
}
break; // State transition failed. Try again.
case STATE_REQUESTED:
if (compareAndSet(STATE_REQUESTED, STATE_TERMINATED)) {
deliverResponse(response);
return;
}
break; // State transition failed. Try again.
case STATE_HAS_RESPONSE:
case STATE_TERMINATED:
throw new AssertionError();
default:
throw new IllegalStateException("Unknown state: " + state);
}
}
}
private void deliverResponse(Response response) {
try {
if (!isUnsubscribed()) {
subscriber.onNext(response);
}
} catch (OnCompletedFailedException
| OnErrorFailedException
| OnErrorNotImplementedException e) {
e.printStackTrace();
return;
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
try {
subscriber.onError(t);
} catch (OnCompletedFailedException
| OnErrorFailedException
| OnErrorNotImplementedException e) {
e.printStackTrace();
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
inner.printStackTrace();
}
return;
}
try {
if (!isUnsubscribed()) {
subscriber.onCompleted();
}
} catch (OnCompletedFailedException
| OnErrorFailedException
| OnErrorNotImplementedException e) {
e.printStackTrace();
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
t.printStackTrace();
}
}
void emitError(Throwable t) {
set(STATE_TERMINATED);
if (!isUnsubscribed()) {
try {
subscriber.onError(t);
} catch (OnCompletedFailedException
| OnErrorFailedException
| OnErrorNotImplementedException e) {
e.printStackTrace();
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
inner.printStackTrace();
}
}
}
}