/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.aurora.scheduler.updater;
import java.util.Objects;
import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Singleton;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.AbstractModule;
import com.google.inject.PrivateModule;
import com.google.inject.TypeLiteral;
import org.apache.aurora.common.args.Arg;
import org.apache.aurora.common.args.CmdLine;
import org.apache.aurora.common.quantity.Amount;
import org.apache.aurora.common.quantity.Time;
import org.apache.aurora.scheduler.SchedulerServicesModule;
import org.apache.aurora.scheduler.base.AsyncUtil;
import org.apache.aurora.scheduler.base.TaskGroupKey;
import org.apache.aurora.scheduler.events.PubsubEventModule;
import org.apache.aurora.scheduler.preemptor.BiCache;
import org.apache.aurora.scheduler.preemptor.BiCache.BiCacheSettings;
import org.apache.aurora.scheduler.storage.entities.IInstanceKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Binding module for scheduling logic and higher-level state management.
*/
public class UpdaterModule extends AbstractModule {
private static final Logger LOG = LoggerFactory.getLogger(UpdaterModule.class);
private final ScheduledExecutorService executor;
private final boolean enableAffinity;
@CmdLine(name = "enable_update_affinity", help = "Enable best-effort affinity of task updates.")
private static final Arg<Boolean> ENABLE_AFFINITY = Arg.create(false);
@CmdLine(name = "update_affinity_reservation_hold_time",
help = "How long to wait for a reserved agent to reoffer freed up resources.")
private static final Arg<Amount<Long, Time>> AFFINITY_EXPIRATION =
Arg.create(Amount.of(3L, Time.MINUTES));
public UpdaterModule() {
this(AsyncUtil.singleThreadLoggingScheduledExecutor("updater-%d", LOG), ENABLE_AFFINITY.get());
}
@VisibleForTesting
UpdaterModule(ScheduledExecutorService executor, boolean enableAffinity) {
this.executor = Objects.requireNonNull(executor);
this.enableAffinity = enableAffinity;
}
@Override
protected void configure() {
install(new PrivateModule() {
@Override
protected void configure() {
if (enableAffinity) {
bind(BiCacheSettings.class).toInstance(
new BiCacheSettings(AFFINITY_EXPIRATION.get(), "update_affinity"));
bind(new TypeLiteral<BiCache<IInstanceKey, TaskGroupKey>>() { }).in(Singleton.class);
bind(UpdateAgentReserver.class).to(UpdateAgentReserver.UpdateAgentReserverImpl.class);
bind(UpdateAgentReserver.UpdateAgentReserverImpl.class).in(Singleton.class);
} else {
bind(UpdateAgentReserver.class).to(UpdateAgentReserver.NullAgentReserver.class);
bind(UpdateAgentReserver.NullAgentReserver.class).in(Singleton.class);
}
expose(UpdateAgentReserver.class);
bind(ScheduledExecutorService.class).toInstance(executor);
bind(UpdateFactory.class).to(UpdateFactory.UpdateFactoryImpl.class);
bind(UpdateFactory.UpdateFactoryImpl.class).in(Singleton.class);
bind(JobUpdateController.class).to(JobUpdateControllerImpl.class);
bind(JobUpdateControllerImpl.class).in(Singleton.class);
expose(JobUpdateController.class);
bind(JobUpdateEventSubscriber.class);
expose(JobUpdateEventSubscriber.class);
}
});
PubsubEventModule.bindSubscriber(binder(), JobUpdateEventSubscriber.class);
SchedulerServicesModule.addSchedulerActiveServiceBinding(binder())
.to(JobUpdateEventSubscriber.class);
}
}