/* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.squareup.okhttp; import com.squareup.okhttp.internal.http.ResponseHeaders; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; final class Dispatcher { // TODO: thread pool size should be configurable; possibly configurable per host. private final ThreadPoolExecutor executorService = new ThreadPoolExecutor( 8, 8, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); private final Map<Object, List<Job>> enqueuedJobs = new LinkedHashMap<Object, List<Job>>(); public synchronized void enqueue( OkHttpClient client, Request request, Response.Receiver responseReceiver) { Job job = new Job(this, client, request, responseReceiver); List<Job> jobsForTag = enqueuedJobs.get(request.tag()); if (jobsForTag == null) { jobsForTag = new ArrayList<Job>(2); enqueuedJobs.put(request.tag(), jobsForTag); } jobsForTag.add(job); executorService.execute(job); } public synchronized void cancel(Object tag) { List<Job> jobs = enqueuedJobs.remove(tag); if (jobs == null) return; for (Job job : jobs) { executorService.remove(job); } } synchronized void finished(Job job) { List<Job> jobs = enqueuedJobs.get(job.tag()); if (jobs != null) jobs.remove(job); } static class RealResponseBody extends Response.Body { private final ResponseHeaders responseHeaders; private final InputStream in; RealResponseBody(ResponseHeaders responseHeaders, InputStream in) { this.responseHeaders = responseHeaders; this.in = in; } @Override public boolean ready() throws IOException { return true; } @Override public MediaType contentType() { String contentType = responseHeaders.getContentType(); return contentType != null ? MediaType.parse(contentType) : null; } @Override public long contentLength() { return responseHeaders.getContentLength(); } @Override public InputStream byteStream() throws IOException { return in; } } }