概述
当我在短时间内发送多个请求时,其中一些请求没有收到响应或出现错误。
API
我有一个单例类,其中包含Retrofit服务。我使用这个类执行所有对API的调用,每个调用都返回一些类型的Observable数据。
public class CoreApi {
public static final String BASE_URL = "https://www.example.com/";
private static CoreApi instance;
private CoreApiService service;
public static CoreApi get() {
if (instance == null)
instance = new CoreApi();
retrun instance;
}
private CoreApi() {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
if (BuildConfig.DEBUG)
httpClient.addInterceptor(httpLoggingInterceptor);
httpClient.connectTimeout(60, TimeUnit.SECONDS);
httpClient.readTimeout(60, TimeUnit.SECONDS);
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxErrorHandlingCallAdapterFactory.create())
.client(httpClient.build());
service = (builder.build()).create(CoreApiService.class);
}
public Observable<SomeData> getSomedata(String authorization) {
return service.getSomeData(authorization);
}
}
服务
interface CoreApiService {
@GET("someDataEndpoint/")
Observable<SomeData> getSomeData(@Header("Authorization") String authorizationToken);
}
CALL
我在活动中设置了一个按钮,每次点击它都会调用api:
Button button = (Button) findViewById(R.id.test_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CoreApi.get().getSomeData("JWT thisisexampletokenreplacedforthesakeofthisquestion")
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(new Action1<SomeData>() {
@Override
public void call(SomeData someData) {
// operations are performed on data, irrelevant for the issue as even if I comment them the issue still occurs
}
});
}
});
问题
每当我点击按钮(不要太快),在日志中可以看到请求正在由Retrofit发出。
但是当我开始更快地点击按钮时,我可以在日志中看到请求正在发送,但并非所有请求都收到响应。没有错误,没有超时,没有任何提示。在Logcat中,我只能看到请求已经被发出(如下所示)。
09-19 11:26:05.421 18763-18821/com.myapp.app D/OkHttp: --> GET https://www.example.com/someDataEndpoint/ http/1.1
09-19 11:26:05.421 18763-18821/com.myapp.app D/OkHttp: Authorization: JWT thisisexampletokenreplacedforthesakeofthisquestion
09-19 11:26:05.422 18763-18821/com.myapp.app D/OkHttp: --> END GET
摘要
以上示例被简化了,但是只有在短时间内有大量调用时(不一定是到同一个端点),才会出现这个问题。
起初,当我负责从多个端点按指定顺序刷新用户数据的HandlerThread开始在随机点卡住时,我注意到了这一点,有时在第二次,有时在第十次调用,有时在中间某个位置。奇怪的是,当其中一个调用卡住后,我仍然可以从应用程序的其他位置执行其他调用。