public void registerInsert( final SendableRequest req, boolean persistent, boolean regmeOnly, ObjectContainer container) { if (!isInsertScheduler) throw new IllegalArgumentException("Adding a SendableInsert to a request scheduler!!"); if (persistent) { if (regmeOnly) { long bootID = 0; boolean queueFull = jobRunner.getQueueSize(NativeThread.NORM_PRIORITY) >= QUEUE_THRESHOLD; if (!queueFull) bootID = this.node.bootID; final RegisterMe regme = new RegisterMe(req, req.getPriorityClass(container), schedCore, null, bootID); container.store(regme); if (logMINOR) Logger.minor(this, "Added insert RegisterMe: " + regme); if (!queueFull) { try { jobRunner.queue( new DBJob() { @Override public boolean run(ObjectContainer container, ClientContext context) { container.delete(regme); if (req.isCancelled(container)) { if (logMINOR) Logger.minor(this, "Request already cancelled"); return false; } if (container.ext().isActive(req)) Logger.error(this, "ALREADY ACTIVE: " + req + " in delayed insert register"); container.activate(req, 1); registerInsert(req, true, false, container); container.deactivate(req, 1); return true; } @Override public String toString() { return "registerInsert"; } }, NativeThread.NORM_PRIORITY, false); } catch (DatabaseDisabledException e) { // Impossible, we are already on the database thread. } } else { schedCore.rerunRegisterMeRunner(jobRunner); } container.deactivate(req, 1); return; } schedCore.innerRegister(req, random, container, clientContext, null); starter.wakeUp(); } else { schedTransient.innerRegister(req, random, null, clientContext, null); starter.wakeUp(); } }
public void removeFromAllRequestsByClientRequest( ClientRequester clientRequest, SendableRequest get, boolean dontComplain, ObjectContainer container) { if (get.persistent()) schedCore.removeFromAllRequestsByClientRequest(get, clientRequest, dontComplain, container); else schedTransient.removeFromAllRequestsByClientRequest(get, clientRequest, dontComplain, null); }
/** * @param request * @param container * @return True if the queue is now full/over-full. */ boolean addToStarterQueue(SendableRequest request, ObjectContainer container) { if (logMINOR) Logger.minor(this, "Adding to starter queue: " + request); container.activate(request, 1); PersistentChosenRequest chosen; try { chosen = new PersistentChosenRequest( request, request.getPriorityClass(container), container, ClientRequestScheduler.this, clientContext); } catch (NoValidBlocksException e) { return false; } if (logMINOR) Logger.minor(this, "Created PCR: " + chosen); container.deactivate(request, 1); boolean dumpNew = false; synchronized (starterQueue) { for (PersistentChosenRequest req : starterQueue) { if (req.request == request) { Logger.error( this, "Already on starter queue: " + req + " for " + request, new Exception("debug")); dumpNew = true; break; } } if (!dumpNew) { starterQueue.add(chosen); int length = starterQueueLength(); length += chosen.sizeNotStarted(); runningPersistentRequests.add(request); if (logMINOR) Logger.minor( this, "Added to running persistent requests, size now " + runningPersistentRequests.size() + " : " + request); return length > MAX_STARTER_QUEUE_SIZE; } } if (dumpNew) chosen.onDumped(schedCore, container, false); return false; }
@Override public void removeRunningRequest(SendableRequest request, ObjectContainer container) { synchronized (starterQueue) { for (int i = 0; i < runningPersistentRequests.size(); i++) { if (runningPersistentRequests.get(i) == request) { runningPersistentRequests.remove(i); i--; if (logMINOR) Logger.minor( this, "Removed running request " + request + " size now " + runningPersistentRequests.size()); } } } // We *DO* need to call clearCooldown here because it only becomes runnable for persistent // requests after it has been removed from starterQueue. boolean active = container.ext().isActive(request); if (!active) container.activate(request, 1); request.clearCooldown(container, clientContext, false); if (!active) container.deactivate(request, 1); }
/** * Compare a recently registered SendableRequest to what is already on the starter queue. If it is * better, kick out stuff from the queue until we are just over the limit. * * @param req * @param container */ public void maybeAddToStarterQueue( SendableRequest req, ObjectContainer container, SendableRequest[] mightBeActive) { short prio = req.getPriorityClass(container); if (logMINOR) Logger.minor(this, "Maybe adding to starter queue: prio=" + prio); synchronized (starterQueue) { boolean betterThanSome = false; int size = 0; PersistentChosenRequest prev = null; for (PersistentChosenRequest old : starterQueue) { if (old.request == req) { // Wait for a reselect. Otherwise we can starve other // requests. Note that this happens with persistent SBI's: // they are added at the new retry count before being // removed at the old retry count. if (logMINOR) Logger.minor(this, "Already on starter queue: " + old + " for " + req); return; } if (prev == old) Logger.error(this, "ON STARTER QUEUE TWICE: " + prev + " for " + prev.request); if (prev != null && prev.request == old.request) Logger.error( this, "REQUEST ON STARTER QUEUE TWICE: " + prev + " for " + prev.request + " vs " + old + " for " + old.request); boolean ignoreActive = false; if (mightBeActive != null) { for (SendableRequest tmp : mightBeActive) if (tmp == old.request) ignoreActive = true; } if (!ignoreActive) { if (container.ext().isActive(old.request)) Logger.warning( this, "REQUEST ALREADY ACTIVATED: " + old.request + " for " + old + " while checking request queue in maybeAddToStarterQueue for " + req); else if (logDEBUG) Logger.debug( this, "Not already activated for " + old + " in while checking request queue in maybeAddToStarterQueue for " + req); } else if (logMINOR) Logger.minor( this, "Ignoring active because just registered: " + old.request + " in maybeAddToStarterQueue for " + req); size += old.sizeNotStarted(); if (old.prio > prio) betterThanSome = true; if (old.request == req) return; prev = old; } if (size >= MAX_STARTER_QUEUE_SIZE && !betterThanSome) { if (logMINOR) Logger.minor( this, "Not adding to starter queue: over limit and req not better than any queued requests"); return; } } addToStarterQueue(req, container); trimStarterQueue(container); }