package freenet.client.async; import freenet.keys.ClientKey; import freenet.keys.Key; import freenet.node.LowLevelGetException; import freenet.node.LowLevelPutException; import freenet.node.NodeClientCore; import freenet.node.RequestScheduler; import freenet.node.SendableRequestItem; import freenet.node.SendableRequestSender; /** * A single selected request, including everything needed to execute it. Most important functions * are the callbacks, which run off-thread, call the upstream callbacks on the SendableGet etc, and * remove the fetching keys from the KeysFetchingLocally. * @author Matthew Toseland <toad@amphibian.dyndns.org> (0xE43DA450) */ public abstract class ChosenBlock { /** The token indicating the key within the request to be fetched/inserted. * Meaning is entirely defined by the request. */ public transient final SendableRequestItem token; /** The key to be fetched, null if not a BaseSendableGet */ public transient final Key key; /** The client-layer key to be fetched, null if not a SendableGet */ public transient final ClientKey ckey; public transient final boolean localRequestOnly; public transient final boolean ignoreStore; public transient final boolean canWriteClientCache; public transient final boolean forkOnCacheable; public transient final boolean realTimeFlag; public ChosenBlock(SendableRequestItem token, Key key, ClientKey ckey, boolean localRequestOnly, boolean ignoreStore, boolean canWriteClientCache, boolean forkOnCacheable, boolean realTimeFlag, RequestScheduler sched) { this.token = token; if(token == null) throw new NullPointerException(); this.key = key; this.ckey = ckey; this.localRequestOnly = localRequestOnly; this.ignoreStore = ignoreStore; this.canWriteClientCache = canWriteClientCache; this.forkOnCacheable = forkOnCacheable; this.realTimeFlag = realTimeFlag; } public abstract boolean isPersistent(); public abstract boolean isCancelled(); public abstract void onFailure(LowLevelPutException e, ClientContext context); public abstract void onInsertSuccess(ClientKey key, ClientContext context); public abstract void onFailure(LowLevelGetException e, ClientContext context); /** * The actual data delivery goes through CRS.tripPendingKey(). This is just a notification * for book-keeping purposes. We call the scheduler to tell it that the request succeeded, * so that it can be rescheduled soon for more requests. * @param context Might be useful. */ public abstract void onFetchSuccess(ClientContext context); public abstract short getPriority(); private boolean sendIsBlocking; public boolean send(NodeClientCore core, RequestScheduler sched) { ClientContext context = sched.getContext(); SendableRequestSender sender = getSender(context); sendIsBlocking = sender.sendIsBlocking(); return sender.send(core, sched, context, this); } public abstract SendableRequestSender getSender(ClientContext context); public void onDumped() { token.dump(); } /** Call this after send() */ public boolean sendIsBlocking() { return sendIsBlocking; } }