/* This code is part of Freenet. It is distributed under the GNU General * Public License, version 2 (or at your option any later version). See * http://www.gnu.org/ for further details of the GPL. */ package freenet.node; import freenet.client.InsertException; import freenet.client.async.ClientContext; import freenet.client.async.ClientRequestScheduler; import freenet.keys.ClientKey; import freenet.support.Logger; import freenet.support.io.NativeThread; import freenet.support.io.ResumeFailedException; /** * Callback interface for a low level insert, which is immediately sendable. These * should be registered on the ClientRequestScheduler when we want to send them. It will * then, when it is time to send, create a thread, send the request, and call the * callback below. */ public abstract class SendableInsert extends SendableRequest { private static final long serialVersionUID = 1L; public SendableInsert(boolean persistent, boolean realTimeFlag) { super(persistent, realTimeFlag); } /** Called when we successfully insert the data */ public abstract void onSuccess(SendableRequestItem keyNum, ClientKey key, ClientContext context); /** Called when we don't! */ public abstract void onFailure(LowLevelPutException e, SendableRequestItem keyNum, ClientContext context); @Override public void internalError(Throwable t, RequestScheduler sched, ClientContext context, boolean persistent) { Logger.error(this, "Internal error on "+this+" : "+t, t); sched.callFailure(this, new LowLevelPutException(LowLevelPutException.INTERNAL_ERROR, t.getMessage(), t), NativeThread.MAX_PRIORITY, persistent); } @Override public final boolean isInsert() { return true; } @Override public ClientRequestScheduler getScheduler(ClientContext context) { if(isSSK()) return context.getSskInsertScheduler(realTimeFlag); else return context.getChkInsertScheduler(realTimeFlag); } public abstract boolean canWriteClientCache(); public abstract boolean localRequestOnly(); public abstract boolean forkOnCacheable(); /** Encoded a key */ public abstract void onEncode(SendableRequestItem token, ClientKey key, ClientContext context); public abstract boolean isEmpty(); @Override public long getWakeupTime(ClientContext context, long now) { if(isEmpty()) return -1; return 0; } private transient boolean resumed = false; public final void onResume(ClientContext context) throws InsertException, ResumeFailedException { synchronized(this) { if(resumed) return; resumed = true; } innerOnResume(context); } protected abstract void innerOnResume(ClientContext context) throws InsertException, ResumeFailedException; }