Skip to content

Commit

Permalink
ping proxy after starting to make sure it works fine
Browse files Browse the repository at this point in the history
  • Loading branch information
danikula committed Sep 25, 2015
1 parent edb12b5 commit e135bf0
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 5 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repositories {
maven { url 'https://dl.bintray.com/alexeydanilov/maven' }
}
dependencies {
compile 'com.danikula:videocache:2.1.2'
compile 'com.danikula:videocache:2.1.3'
}
```

Expand Down Expand Up @@ -59,6 +59,9 @@ More preferable way is use some dependency injector like [Dagger](http://square.
See `sample` app for details.

## Whats new
### 2.1.3
- ping proxy after starting to make sure it works fine

### 2.1.2
- fix offline work

Expand Down
2 changes: 1 addition & 1 deletion library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ publish {
userOrg = 'alexeydanilov'
groupId = 'com.danikula'
artifactId = 'videocache'
publishVersion = '2.1.2'
publishVersion = '2.1.3'
description = 'Cache support for android VideoView'
website = 'https://github.com/danikula/AndroidVideoCache'
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
package com.danikula.videocache;

import android.os.SystemClock;
import android.util.Log;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static com.danikula.videocache.Preconditions.checkAllNotNull;
import static com.danikula.videocache.Preconditions.checkNotNull;
Expand Down Expand Up @@ -39,6 +47,8 @@
public class HttpProxyCacheServer {

private static final String PROXY_HOST = "127.0.0.1";
private static final String PING_REQUEST = "ping";
private static final String PING_RESPONSE = "ping ok";

private final Object clientsLock = new Object();
private final ExecutorService socketProcessor = Executors.newFixedThreadPool(8);
Expand All @@ -47,6 +57,7 @@ public class HttpProxyCacheServer {
private final int port;
private final Thread waitConnectionThread;
private final FileNameGenerator fileNameGenerator;
private boolean pinged;

public HttpProxyCacheServer(FileNameGenerator fileNameGenerator) {
this.fileNameGenerator = checkNotNull(fileNameGenerator);
Expand All @@ -58,13 +69,65 @@ public HttpProxyCacheServer(FileNameGenerator fileNameGenerator) {
this.waitConnectionThread = new Thread(new WaitRequestsRunnable(startSignal));
this.waitConnectionThread.start();
startSignal.await(); // freeze thread, wait for server starts
Log.i(LOG_TAG, "Proxy cache server started. Ping it...");
makeSureServerWorks();
} catch (IOException | InterruptedException e) {
socketProcessor.shutdown();
throw new IllegalStateException("Error starting local proxy server", e);
}
}

private void makeSureServerWorks() {
int maxPingAttempts = 3;
int delay = 100;
int pingAttempts = 0;
while (pingAttempts < maxPingAttempts) {
try {
Future<Boolean> pingFuture = socketProcessor.submit(new PingCallable());
pinged = pingFuture.get(delay, TimeUnit.MILLISECONDS);
if (pinged) {
return;
}
pingAttempts++;
SystemClock.sleep(delay);
delay *= 2;
} catch (InterruptedException | ExecutionException | TimeoutException e) {
Log.e(LOG_TAG, "Error pinging server. Shutdown it... If you see this message, please, email me [email protected]", e);
}
}

if (!pinged) {
shutdown();
}
}

private boolean pingServer() throws ProxyCacheException {
String pingUrl = appendToProxyUrl(PING_REQUEST);
HttpUrlSource source = new HttpUrlSource(pingUrl);
try {
byte[] expectedResponse = PING_RESPONSE.getBytes();
source.open(0);
byte[] response = new byte[expectedResponse.length];
source.read(response);
boolean pingOk = Arrays.equals(expectedResponse, response);
Log.d(LOG_TAG, "Ping response: `" + new String(response) + "`, pinged? " + pingOk);
return pingOk;
} catch (ProxyCacheException e) {
Log.e(LOG_TAG, "Error reading ping response", e);
return false;
} finally {
source.close();
}
}

public String getProxyUrl(String url) {
if (!pinged) {
Log.e(LOG_TAG, "Proxy server isn't pinged. Caching doesn't work. If you see this message, please, email me [email protected]");
}
return pinged ? appendToProxyUrl(url) : url;
}

private String appendToProxyUrl(String url) {
return String.format("http://%s:%d/%s", PROXY_HOST, port, ProxyCacheUtils.encode(url));
}

Expand Down Expand Up @@ -140,8 +203,12 @@ private void processSocket(Socket socket) {
GetRequest request = GetRequest.read(socket.getInputStream());
Log.i(LOG_TAG, "Request to cache proxy:" + request);
String url = ProxyCacheUtils.decode(request.uri);
HttpProxyCacheServerClients clients = getClients(url);
clients.processRequest(request, socket);
if (PING_REQUEST.equals(url)) {
responseToPing(socket);
} else {
HttpProxyCacheServerClients clients = getClients(url);
clients.processRequest(request, socket);
}
} catch (SocketException e) {
// There is no way to determine that client closed connection http://stackoverflow.com/a/10241044/999458
// So just to prevent log flooding don't log stacktrace
Expand All @@ -154,6 +221,12 @@ private void processSocket(Socket socket) {
}
}

private void responseToPing(Socket socket) throws IOException {
OutputStream out = socket.getOutputStream();
out.write("HTTP/1.1 200 OK\n\n".getBytes());
out.write(PING_RESPONSE.getBytes());
}

private HttpProxyCacheServerClients getClients(String url) throws ProxyCacheException {
synchronized (clientsLock) {
HttpProxyCacheServerClients clients = clientsMap.get(url);
Expand Down Expand Up @@ -248,4 +321,11 @@ public void run() {
}
}

private class PingCallable implements Callable<Boolean> {

@Override
public Boolean call() throws Exception {
return pingServer();
}
}
}
2 changes: 1 addition & 1 deletion sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ dependencies {
// compile project(':library')
compile 'com.android.support:support-v4:23.0.1'
compile 'org.androidannotations:androidannotations-api:3.3.2'
compile 'com.danikula:videocache:2.1.2'
compile 'com.danikula:videocache:2.1.3'
compile 'com.viewpagerindicator:library:2.4.2-SNAPSHOT@aar'
apt 'org.androidannotations:androidannotations:3.3.2'
}

0 comments on commit e135bf0

Please sign in to comment.