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 reregisterAll( final ClientRequester request, ObjectContainer container, short oldPrio) { schedTransient.reregisterAll(request, random, this, null, clientContext, oldPrio); if (schedCore != null) schedCore.reregisterAll(request, random, this, container, clientContext, oldPrio); starter.wakeUp(); }
public void start() { chkRequestStarterRT.start(); chkInsertStarterRT.start(); sskRequestStarterRT.start(); sskInsertStarterRT.start(); chkRequestStarterBulk.start(); chkInsertStarterBulk.start(); sskRequestStarterBulk.start(); sskInsertStarterBulk.start(); }
private void fillRequestStarterQueue(ObjectContainer container, ClientContext context) { synchronized (this) { if (fillingRequestStarterQueue) return; fillingRequestStarterQueue = true; } long now = System.currentTimeMillis(); try { if (logMINOR) Logger.minor( this, "Filling request queue... (SSK=" + isSSKScheduler + " insert=" + isInsertScheduler); long noLaterThan = Long.MAX_VALUE; boolean checkCooldownQueue = now > nextQueueFillRequestStarterQueue; if ((!isInsertScheduler) && checkCooldownQueue) { if (persistentCooldownQueue != null) noLaterThan = moveKeysFromCooldownQueue(persistentCooldownQueue, true, container); noLaterThan = Math.min( noLaterThan, moveKeysFromCooldownQueue(transientCooldownQueue, false, container)); } // If anything has been re-added, the request starter will have been woken up. short fuzz = -1; if (PRIORITY_SOFT.equals(choosenPriorityScheduler)) fuzz = -1; else if (PRIORITY_HARD.equals(choosenPriorityScheduler)) fuzz = 0; boolean added = false; synchronized (starterQueue) { if (logMINOR && (!isSSKScheduler) && (!isInsertScheduler)) { Logger.minor(this, "Scheduling CHK fetches..."); for (SendableRequest req : runningPersistentRequests) { boolean wasActive = container.ext().isActive(req); if (!wasActive) container.activate(req, 1); Logger.minor(this, "Running persistent request: " + req); if (!wasActive) container.deactivate(req, 1); } } // Recompute starterQueueLength int length = 0; PersistentChosenRequest old = null; for (PersistentChosenRequest req : starterQueue) { if (old == req) Logger.error(this, "DUPLICATE CHOSEN REQUESTS ON QUEUE: " + req); if (old != null && old.request == req.request) Logger.error( this, "DUPLICATE REQUEST ON QUEUE: " + old + " vs " + req + " both " + req.request); boolean ignoreActive = false; if (!ignoreActive) { if (container.ext().isActive(req.request)) Logger.warning( this, "REQUEST ALREADY ACTIVATED: " + req.request + " for " + req + " while checking request queue in filling request queue"); else if (logMINOR) Logger.minor( this, "Not already activated for " + req + " in while checking request queue in filling request queue"); } else if (logMINOR) Logger.minor(this, "Ignoring active because just registered: " + req.request); req.pruneDuplicates(ClientRequestScheduler.this); old = req; length += req.sizeNotStarted(); } if (logMINOR) Logger.minor( this, "Queue size: " + length + " SSK=" + isSSKScheduler + " insert=" + isInsertScheduler); if (length > MAX_STARTER_QUEUE_SIZE * 3 / 4) { if (length >= WARNING_STARTER_QUEUE_SIZE) Logger.error(this, "Queue already full: " + length); return; } } if ((!isSSKScheduler) && (!isInsertScheduler)) { Logger.minor(this, "Scheduling CHK fetches..."); } boolean addedMore = false; while (true) { SelectorReturn r; // Must synchronize on scheduler to avoid problems with cooldown queue. See notes on // CooldownTracker.clearCachedWakeup, which also applies to other cooldown operations. synchronized (this) { r = selector.removeFirstInner( fuzz, random, offeredKeys, starter, schedCore, schedTransient, false, true, Short.MAX_VALUE, isRTScheduler, context, container, now); } SendableRequest request = null; if (r != null && r.req != null) request = r.req; else { if (r != null && r.wakeupTime > 0 && noLaterThan > r.wakeupTime) { noLaterThan = r.wakeupTime; if (logMINOR) Logger.minor( this, "Waking up in " + TimeUtil.formatTime(noLaterThan - now) + " for cooldowns"); } } if (request == null) { synchronized (ClientRequestScheduler.this) { // Don't wake up for a while, but no later than the time we expect the next item to come // off the cooldown queue if (checkCooldownQueue && !added) { nextQueueFillRequestStarterQueue = System.currentTimeMillis() + WAIT_AFTER_NOTHING_TO_START; if (nextQueueFillRequestStarterQueue > noLaterThan) nextQueueFillRequestStarterQueue = noLaterThan + 1; } } if (addedMore) starter.wakeUp(); return; } boolean full = addToStarterQueue(request, container); container.deactivate(request, 1); if (!added) starter.wakeUp(); else addedMore = true; added = true; if (full) { if (addedMore) starter.wakeUp(); return; } } } finally { synchronized (this) { fillingRequestStarterQueue = false; } } }
void finishRegister( final SendableGet[] getters, boolean persistent, ObjectContainer container, final boolean anyValid, final DatastoreCheckerItem reg) { if (logMINOR) Logger.minor( this, "finishRegister for " + getters + " anyValid=" + anyValid + " reg=" + reg + " persistent=" + persistent); if (isInsertScheduler) { IllegalStateException e = new IllegalStateException("finishRegister on an insert scheduler"); for (int i = 0; i < getters.length; i++) { if (persistent) container.activate(getters[i], 1); getters[i].internalError(e, this, container, clientContext, persistent); if (persistent) container.deactivate(getters[i], 1); } throw e; } if (persistent) { // Add to the persistent registration queue if (!databaseExecutor.onThread()) { throw new IllegalStateException("Not on database thread!"); } if (persistent) container.activate(getters, 1); if (logMINOR) Logger.minor(this, "finishRegister() for " + getters); if (anyValid) { boolean wereAnyValid = false; for (int i = 0; i < getters.length; i++) { SendableGet getter = getters[i]; container.activate(getter, 1); // Just check isCancelled, we have already checked the cooldown. if (!(getter.isCancelled(container))) { wereAnyValid = true; if (!getter.preRegister(container, clientContext, true)) { schedCore.innerRegister(getter, random, container, clientContext, getters); } } else getter.preRegister(container, clientContext, false); } if (!wereAnyValid) { Logger.normal(this, "No requests valid: " + getters); } } else { Logger.normal(this, "No valid requests passed in: " + getters); } if (reg != null) container.delete(reg); queueFillRequestStarterQueue(true); } else { // Register immediately. for (int i = 0; i < getters.length; i++) { if ((!anyValid) || getters[i].isCancelled(null)) { getters[i].preRegister(container, clientContext, false); continue; } else { if (getters[i].preRegister(container, clientContext, true)) continue; } if (!getters[i].isCancelled(null)) schedTransient.innerRegister(getters[i], random, null, clientContext, getters); } starter.wakeUp(); } }
@Override public void wakeStarter() { starter.wakeUp(); }
/** Queue the offered key */ public void queueOfferedKey(final Key key, boolean realTime) { if (logMINOR) Logger.minor(this, "queueOfferedKey(" + key); offeredKeys.queueKey(key); starter.wakeUp(); }
RequestStarterGroup( Node node, NodeClientCore core, int portNumber, RandomSource random, Config config, SimpleFieldSet fs, ClientContext ctx, long dbHandle) throws InvalidConfigValueException { SubConfig schedulerConfig = config.createSubConfig("node.scheduler"); this.stats = core.nodeStats; throttleWindowBulk = new ThrottleWindowManager(2.0, fs == null ? null : fs.subset("ThrottleWindow"), node); throttleWindowRT = new ThrottleWindowManager(2.0, fs == null ? null : fs.subset("ThrottleWindowRT"), node); throttleWindowCHK = new ThrottleWindowManager(2.0, fs == null ? null : fs.subset("ThrottleWindowCHK"), node); throttleWindowSSK = new ThrottleWindowManager(2.0, fs == null ? null : fs.subset("ThrottleWindowSSK"), node); throttleWindowInsert = new ThrottleWindowManager(2.0, fs == null ? null : fs.subset("ThrottleWindowInsert"), node); throttleWindowRequest = new ThrottleWindowManager( 2.0, fs == null ? null : fs.subset("ThrottleWindowRequest"), node); chkRequestThrottleBulk = new MyRequestThrottle( 5000, "CHK Request", fs == null ? null : fs.subset("CHKRequestThrottle"), 32768, false); chkRequestThrottleRT = new MyRequestThrottle( 5000, "CHK Request (RT)", fs == null ? null : fs.subset("CHKRequestThrottleRT"), 32768, true); chkRequestStarterBulk = new RequestStarter( core, chkRequestThrottleBulk, "CHK Request starter (" + portNumber + ')', stats.requestOutputThrottle, stats.requestInputThrottle, stats.localChkFetchBytesSentAverage, stats.localChkFetchBytesReceivedAverage, false, false, false); chkRequestStarterRT = new RequestStarter( core, chkRequestThrottleRT, "CHK Request starter (" + portNumber + ')', stats.requestOutputThrottle, stats.requestInputThrottle, stats.localChkFetchBytesSentAverage, stats.localChkFetchBytesReceivedAverage, false, false, true); chkFetchSchedulerBulk = new ClientRequestScheduler( false, false, false, random, chkRequestStarterBulk, node, core, "CHKrequester", ctx); chkFetchSchedulerRT = new ClientRequestScheduler( false, false, true, random, chkRequestStarterRT, node, core, "CHKrequester", ctx); chkRequestStarterBulk.setScheduler(chkFetchSchedulerBulk); chkRequestStarterRT.setScheduler(chkFetchSchedulerRT); registerSchedulerConfig( schedulerConfig, "CHKrequester", chkFetchSchedulerBulk, chkFetchSchedulerRT, false, false); // insertThrottle = new ChainedRequestThrottle(10000, 2.0F, requestThrottle); // FIXME reenable the above chkInsertThrottleBulk = new MyRequestThrottle( 20000, "CHK Insert", fs == null ? null : fs.subset("CHKInsertThrottle"), 32768, false); chkInsertThrottleRT = new MyRequestThrottle( 20000, "CHK Insert (RT)", fs == null ? null : fs.subset("CHKInsertThrottleRT"), 32768, true); chkInsertStarterBulk = new RequestStarter( core, chkInsertThrottleBulk, "CHK Insert starter (" + portNumber + ')', stats.requestOutputThrottle, stats.requestInputThrottle, stats.localChkInsertBytesSentAverage, stats.localChkInsertBytesReceivedAverage, true, false, false); chkInsertStarterRT = new RequestStarter( core, chkInsertThrottleRT, "CHK Insert starter (" + portNumber + ')', stats.requestOutputThrottle, stats.requestInputThrottle, stats.localChkInsertBytesSentAverage, stats.localChkInsertBytesReceivedAverage, true, false, true); chkPutSchedulerBulk = new ClientRequestScheduler( true, false, false, random, chkInsertStarterBulk, node, core, "CHKinserter", ctx); chkPutSchedulerRT = new ClientRequestScheduler( true, false, true, random, chkInsertStarterRT, node, core, "CHKinserter", ctx); chkInsertStarterBulk.setScheduler(chkPutSchedulerBulk); chkInsertStarterRT.setScheduler(chkPutSchedulerRT); registerSchedulerConfig( schedulerConfig, "CHKinserter", chkPutSchedulerBulk, chkPutSchedulerRT, false, true); sskRequestThrottleBulk = new MyRequestThrottle( 5000, "SSK Request", fs == null ? null : fs.subset("SSKRequestThrottle"), 1024, false); sskRequestThrottleRT = new MyRequestThrottle( 5000, "SSK Request (RT)", fs == null ? null : fs.subset("SSKRequestThrottleRT"), 1024, true); sskRequestStarterBulk = new RequestStarter( core, sskRequestThrottleBulk, "SSK Request starter (" + portNumber + ')', stats.requestOutputThrottle, stats.requestInputThrottle, stats.localSskFetchBytesSentAverage, stats.localSskFetchBytesReceivedAverage, false, true, false); sskRequestStarterRT = new RequestStarter( core, sskRequestThrottleRT, "SSK Request starter (" + portNumber + ')', stats.requestOutputThrottle, stats.requestInputThrottle, stats.localSskFetchBytesSentAverage, stats.localSskFetchBytesReceivedAverage, false, true, true); sskFetchSchedulerBulk = new ClientRequestScheduler( false, true, false, random, sskRequestStarterBulk, node, core, "SSKrequester", ctx); sskFetchSchedulerRT = new ClientRequestScheduler( false, true, true, random, sskRequestStarterRT, node, core, "SSKrequester", ctx); sskRequestStarterBulk.setScheduler(sskFetchSchedulerBulk); sskRequestStarterRT.setScheduler(sskFetchSchedulerRT); registerSchedulerConfig( schedulerConfig, "SSKrequester", sskFetchSchedulerBulk, sskFetchSchedulerRT, true, false); // insertThrottle = new ChainedRequestThrottle(10000, 2.0F, requestThrottle); // FIXME reenable the above sskInsertThrottleBulk = new MyRequestThrottle( 20000, "SSK Insert", fs == null ? null : fs.subset("SSKInsertThrottle"), 1024, false); sskInsertThrottleRT = new MyRequestThrottle( 20000, "SSK Insert", fs == null ? null : fs.subset("SSKInsertThrottleRT"), 1024, true); sskInsertStarterBulk = new RequestStarter( core, sskInsertThrottleBulk, "SSK Insert starter (" + portNumber + ')', stats.requestOutputThrottle, stats.requestInputThrottle, stats.localSskInsertBytesSentAverage, stats.localSskFetchBytesReceivedAverage, true, true, false); sskInsertStarterRT = new RequestStarter( core, sskInsertThrottleRT, "SSK Insert starter (" + portNumber + ')', stats.requestOutputThrottle, stats.requestInputThrottle, stats.localSskInsertBytesSentAverage, stats.localSskFetchBytesReceivedAverage, true, true, true); sskPutSchedulerBulk = new ClientRequestScheduler( true, true, false, random, sskInsertStarterBulk, node, core, "SSKinserter", ctx); sskPutSchedulerRT = new ClientRequestScheduler( true, true, true, random, sskInsertStarterRT, node, core, "SSKinserter", ctx); sskInsertStarterBulk.setScheduler(sskPutSchedulerBulk); sskInsertStarterRT.setScheduler(sskPutSchedulerRT); registerSchedulerConfig( schedulerConfig, "SSKinserter", sskPutSchedulerBulk, sskPutSchedulerRT, true, true); schedulerConfig.finishedInitialization(); }