/* * Created by Angel Leon (@gubatron), Alden Torres (aldenml) * Copyright (c) 2011-2014, FrostWire(R). All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.frostwire.search.domainalias; import java.util.concurrent.ExecutorService; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import com.frostwire.concurrent.DefaultThreadFactory; import com.frostwire.util.HttpClient; import com.frostwire.util.HttpClientFactory; /** * @author gubatron * @author aldenml * */ public class DomainAlias { public static final ExecutorService executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 30L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new DefaultThreadFactory("DomainAliasCheckers", true)); public final String original; public final String alias; private DomainAliasState aliasState; private long lastChecked; private int failedAttempts; private final static long DOMAIN_ALIAS_CHECK_INTERVAL_MILLISECONDS = 5000;//time to wait before we check again this domain alias after it's been marked offline. private final static int DOMAIN_ALIAS_CHECK_TIMEOUT_MILLISECONDS = 3500; public DomainAlias(String original, String alias) { this.original = original; this.alias = alias; lastChecked = -1; aliasState = DomainAliasState.UNCHECKED; failedAttempts = 0; } public long getLastChecked() { return lastChecked; } public DomainAliasState getState() { return aliasState; } public String getOriginal() { return original; } public String getAlias() { return alias; } public void checkStatus(final DomainAliasPongListener pongListener) { if (aliasState != DomainAliasState.CHECKING) { long timeSinceLastCheck = System.currentTimeMillis() - lastChecked; if (timeSinceLastCheck > DOMAIN_ALIAS_CHECK_INTERVAL_MILLISECONDS) { Thread r = new Thread("DomainAlias-Pinger (" + original + "=>" + alias + ")") { @Override public void run() { pingAlias(pongListener); } }; executor.execute(r); } else { System.out.println("DomainAlias.checkStatus: Too early to ping again " + alias); } } else { System.out.println("DomainAlias.checkStatus: Not checking " + alias +" because it's still CHECKING"); } } private void pingAlias(final DomainAliasPongListener pongListener) { aliasState = DomainAliasState.CHECKING; lastChecked = System.currentTimeMillis(); if (ping(alias)) { System.out.println(alias + " Domain alias pong! "); aliasState = DomainAliasState.ONLINE; failedAttempts = 0; pongListener.onDomainAliasPong(this); } else { pingFailed(); pongListener.onDomainAliasPingFailed(this); } } private static boolean ping(String domainName) { boolean pong = false; try { HttpClient httpClient = HttpClientFactory.newDefaultInstance(); String string = httpClient.get("http://"+domainName, DOMAIN_ALIAS_CHECK_TIMEOUT_MILLISECONDS); pong = string != null && string.length()> 0; } catch (Throwable t) { System.out.println("No pong from " + domainName + ".\n"); } return pong; } private void pingFailed() { aliasState = DomainAliasState.OFFLINE; failedAttempts++; } public void markOffline() { aliasState = DomainAliasState.OFFLINE; lastChecked = System.currentTimeMillis(); } public int getFailedAttempts() { return failedAttempts; } @Override public boolean equals(Object obj) { DomainAlias other = (DomainAlias) obj; return other!=null && this.original.equals(other.original) && this.alias.equals(other.alias); } @Override public int hashCode() { return (this.original.hashCode() * 29) + (this.alias.hashCode() * 13); } @Override public String toString() { return "("+original+" => "+alias + " [" + aliasState + "])"; } public void reset() { this.aliasState = DomainAliasState.UNCHECKED; this.failedAttempts = 0; this.lastChecked = -1; } }