1 package org.oxerr.webmagic.proxy; 2 3 import java.io.Externalizable; 4 import java.io.IOException; 5 import java.io.ObjectInput; 6 import java.io.ObjectOutput; 7 import java.net.URI; 8 import java.time.Duration; 9 import java.time.Instant; 10 import java.util.concurrent.Delayed; 11 import java.util.concurrent.TimeUnit; 12 import java.util.concurrent.atomic.AtomicLong; 13 14 import org.apache.commons.lang3.builder.CompareToBuilder; 15 import org.apache.commons.lang3.builder.EqualsBuilder; 16 import org.apache.commons.lang3.builder.HashCodeBuilder; 17 18 import us.codecraft.webmagic.proxy.Proxy; 19 20 public class DelayedProxy implements Delayed, Externalizable { 21 22 private transient Proxy proxy; 23 24 private Instant availableTime; 25 26 private AtomicLong successCount; 27 28 private AtomicLong failureCount; 29 30 public DelayedProxy() { 31 this(null); 32 } 33 34 public DelayedProxy(Proxy proxy) { 35 this(proxy, Duration.ZERO); 36 } 37 38 public DelayedProxy(Proxy proxy, Duration duration) { 39 this.proxy = proxy; 40 this.availableTime = Instant.now().plus(duration); 41 this.successCount = new AtomicLong(); 42 this.failureCount = new AtomicLong(); 43 } 44 45 public Proxy getProxy() { 46 return proxy; 47 } 48 49 public void setProxy(Proxy proxy) { 50 this.proxy = proxy; 51 } 52 53 public Instant getAvailableTime() { 54 return availableTime; 55 } 56 57 public void setAvailableTime(Instant availableTime) { 58 this.availableTime = availableTime; 59 } 60 61 public long getSuccessCount() { 62 return successCount.longValue(); 63 } 64 65 public long incrementAndGetSuccessCount() { 66 return successCount.incrementAndGet(); 67 } 68 69 public long getFailureCount() { 70 return failureCount.longValue(); 71 } 72 73 public long incrementAndGetFailureCount() { 74 return this.failureCount.incrementAndGet(); 75 } 76 77 @Override 78 public long getDelay(TimeUnit unit) { 79 Instant now = Instant.now(); 80 Duration duration = Duration.between(now, this.availableTime); 81 return unit.convert(duration); 82 } 83 84 @Override 85 public void writeExternal(ObjectOutput out) throws IOException { 86 out.writeObject(proxy.toURI()); 87 out.writeObject(availableTime); 88 out.writeObject(successCount); 89 out.writeObject(failureCount); 90 } 91 92 @Override 93 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 94 URI uri = (URI) in.readObject(); 95 this.proxy = Proxy.create(uri); 96 this.availableTime = (Instant) in.readObject(); 97 this.successCount = (AtomicLong) in.readObject(); 98 this.failureCount = (AtomicLong) in.readObject(); 99 } 100 101 @Override 102 public int compareTo(Delayed o) { 103 DelayedProxy that = (DelayedProxy) o; 104 return new CompareToBuilder() 105 .append(this.availableTime, that.availableTime) 106 .append(this.proxy.toURI(), that.proxy.toURI()) 107 .toComparison(); 108 } 109 110 @Override 111 public int hashCode() { 112 return new HashCodeBuilder(17, 37) 113 .append(this.availableTime) 114 .append(this.proxy.toURI()) 115 .toHashCode(); 116 } 117 118 @Override 119 public boolean equals(Object obj) { 120 if (obj == null) { 121 return false; 122 } 123 if (obj == this) { 124 return true; 125 } 126 if (obj.getClass() != getClass()) { 127 return false; 128 } 129 DelayedProxy that = (DelayedProxy) obj; 130 return new EqualsBuilder() 131 .append(this.availableTime, that.availableTime) 132 .append(this.proxy.toURI(), that.proxy.toURI()) 133 .isEquals(); 134 } 135 136 }