Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use workspace limit idle timeout value in WorkspaceActivityManager #9395

Merged
merged 7 commits into from Apr 13, 2018
4 changes: 4 additions & 0 deletions assembly/assembly-wsmaster-war/pom.xml
Expand Up @@ -252,6 +252,10 @@
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-api-resource</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-api-workspace-activity</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-keycloak-server</artifactId>
Expand Down
Expand Up @@ -70,6 +70,7 @@
import org.eclipse.che.multiuser.api.permission.server.AdminPermissionInitializer;
import org.eclipse.che.multiuser.api.permission.server.PermissionChecker;
import org.eclipse.che.multiuser.api.permission.server.PermissionCheckerImpl;
import org.eclipse.che.multiuser.api.workspace.activity.MultiUserWorkspaceActivityModule;
import org.eclipse.che.multiuser.keycloak.server.deploy.KeycloakModule;
import org.eclipse.che.multiuser.machine.authentication.server.MachineAuthModule;
import org.eclipse.che.multiuser.organization.api.OrganizationApiModule;
Expand Down Expand Up @@ -191,8 +192,6 @@ protected void configure() {

bind(org.eclipse.che.api.deploy.WsMasterAnalyticsAddresser.class);

install(new org.eclipse.che.api.workspace.activity.inject.WorkspaceActivityModule());

install(new org.eclipse.che.api.core.rest.CoreRestModule());
install(new org.eclipse.che.api.core.util.FileCleaner.FileCleanerModule());
install(new org.eclipse.che.swagger.deploy.DocsModule());
Expand Down Expand Up @@ -263,6 +262,8 @@ private void configureSingleUserMode(Map<String, String> persistenceProperties)
.to(org.eclipse.che.security.oauth.OAuthAuthenticatorTokenProvider.class);
bind(org.eclipse.che.security.oauth.OAuthAuthenticationService.class);
bind(RemoteSubscriptionStorage.class).to(InmemoryRemoteSubscriptionStorage.class);

install(new org.eclipse.che.api.workspace.activity.inject.WorkspaceActivityModule());
}

private void configureMultiUserMode(
Expand All @@ -287,6 +288,7 @@ private void configureMultiUserMode(
install(
new org.eclipse.che.multiuser.permission.workspace.server.jpa
.MultiuserWorkspaceJpaModule());
install(new MultiUserWorkspaceActivityModule());

// Permission filters
bind(org.eclipse.che.multiuser.permission.system.SystemServicePermissionsFilter.class);
Expand Down
Expand Up @@ -106,12 +106,6 @@ che.workspace.hosts=NULL

che.installer.registry.remote=NULL

# Idle Timeout
# The system will suspend the workspace if the end user is idle for
# this amount of time. Idleness is determined by the length of time that a user has
# not interacted with the workspace. Leaving a browser window open counts as idleness time.
che.workspace.agent.dev.inactive_stop_timeout_ms=3600000
#
# Period of inactive workspaces suspend job execution.
che.workspace.activity_check_scheduler_period_s=60
#
Expand Down
Expand Up @@ -33,3 +33,6 @@ che.infra.kubernetes.tls_enabled=che.infra.openshift.tls_enabled

che.infra.docker.daemon_url=docker.client.daemon_url
che.infra.docker.certificates_folder=docker.client.certificates_folder

# old name of property has been removed due to https://github.com/eclipse/che/issues/8951
che.limits.workspace.idle.timeout=che.workspace.agent.dev.inactive_stop_timeout_ms
10 changes: 1 addition & 9 deletions dockerfiles/init/manifests/che.env
Expand Up @@ -146,14 +146,6 @@
# Default java command line options to be added to JVM that run maven server.
#CHE_WORKSPACE_MAVEN__SERVER__JAVA__OPTIONS=XX:MaxRAM=128m -XX:MaxRAMFraction=1 -XX:+UseParallelGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xms20m -Djava.security.egd=file:/dev/./urandom


# Workspace Idle timeout
# The length of time after which workspaces will be automatically stopped, if no activity
# has been detected on them. Currently, keyboard and mouse interactions in IDE, as well as HTTP
# requests to ws-agent count as activity. Set "0" to disable automatic stop of inactive workspaces.
# Default to the value of this property in che.properties (3600000)
#CHE_WORKSPACE_AGENT_DEV_INACTIVE__STOP__TIMEOUT__MS=0

########################################################################################
##### #####
##### NETWORKING FOR CHE ON DOCKER #####
Expand Down Expand Up @@ -662,7 +654,7 @@ CHE_SINGLE_PORT=false
# suspend the workspace and then stopping it. Idleness is the
# length of time that the user has not interacted with the workspace, meaning that
# one of our agents has not received interaction. Leaving a browser window open
# counts toward idleness.
# counts toward idleness. Value is provided in milliseconds
#CHE_LIMITS_WORKSPACE_IDLE_TIMEOUT=-1

# The maximum amount of RAM that a user can allocate to a workspace when they
Expand Down
63 changes: 63 additions & 0 deletions multiuser/api/che-multiuser-api-workspace-activity/pom.xml
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (c) 2012-2018 Red Hat, Inc.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html

Contributors:
Red Hat, Inc. - initial API and implementation

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>che-multiuser-api</artifactId>
<groupId>org.eclipse.che.multiuser</groupId>
<version>6.4.0-SNAPSHOT</version>
</parent>
<artifactId>che-multiuser-api-workspace-activity</artifactId>
<packaging>jar</packaging>
<name>Che Multiuser :: Workspace Activity</name>
<dependencies>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-account</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace-activity</artifactId>
<version>6.4.0-SNAPSHOT</version>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove version

</dependency>
<dependency>
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-api-resource</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-api-resource</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-api-resource-shared</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.multiuser.api.workspace.activity;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import java.util.List;
import java.util.Optional;
import org.eclipse.che.account.api.AccountManager;
import org.eclipse.che.account.shared.model.Account;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.workspace.activity.WorkspaceActivityDao;
import org.eclipse.che.api.workspace.activity.WorkspaceActivityManager;
import org.eclipse.che.api.workspace.server.WorkspaceManager;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
import org.eclipse.che.multiuser.resource.api.type.TimeoutResourceType;
import org.eclipse.che.multiuser.resource.api.usage.ResourceManager;
import org.eclipse.che.multiuser.resource.model.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Implementation of WorkspaceActivityManager with overriden retrieval of timeout, with using
* Resource API to get user's limits
*
* @author Mykhailo Kuznietsov
*/
@Singleton
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test added

public class MultiUserWorkspaceActivityManager extends WorkspaceActivityManager {

private static final Logger LOG =
LoggerFactory.getLogger(MultiUserWorkspaceActivityManager.class);

private final AccountManager accountManager;
private final ResourceManager resourceManager;
private final long defaultTimeout;

@Inject
public MultiUserWorkspaceActivityManager(
WorkspaceManager workspaceManager,
WorkspaceActivityDao activityDao,
EventService eventService,
AccountManager accountManager,
ResourceManager resourceManager,
@Named("che.limits.workspace.idle.timeout") long defaultTimeout) {
super(workspaceManager, activityDao, eventService, defaultTimeout);
this.accountManager = accountManager;
this.resourceManager = resourceManager;
this.defaultTimeout = defaultTimeout;
}

@Override
protected long getIdleTimeout(String wsId) {
List<? extends Resource> availableResources;
try {
WorkspaceImpl workspace = workspaceManager.getWorkspace(wsId);
Account account = accountManager.getByName(workspace.getNamespace());
availableResources = resourceManager.getAvailableResources(account.getId());

} catch (NotFoundException | ServerException e) {
LOG.error(e.getLocalizedMessage(), e);
return defaultTimeout;
}
Optional<? extends Resource> timeoutOpt =
availableResources
.stream()
.filter(resource -> TimeoutResourceType.ID.equals(resource.getType()))
.findAny();

if (timeoutOpt.isPresent()) {
return timeoutOpt.get().getAmount() * 60 * 1000;
} else {
return defaultTimeout;
}
}
}
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.multiuser.api.workspace.activity;

import com.google.inject.AbstractModule;
import org.eclipse.che.api.workspace.activity.JpaWorkspaceActivityDao;
import org.eclipse.che.api.workspace.activity.WorkspaceActivityDao;
import org.eclipse.che.api.workspace.activity.WorkspaceActivityManager;
import org.eclipse.che.api.workspace.activity.WorkspaceActivityService;

/**
* Implementation of
*
* @author Mykhailo Kuznietsov
*/
public class MultiUserWorkspaceActivityModule extends AbstractModule {

@Override
protected void configure() {
bind(WorkspaceActivityService.class);
bind(WorkspaceActivityDao.class).to(JpaWorkspaceActivityDao.class);
bind(WorkspaceActivityManager.class).to(MultiUserWorkspaceActivityManager.class);
}
}
1 change: 1 addition & 0 deletions multiuser/api/pom.xml
Expand Up @@ -32,5 +32,6 @@
<module>che-multiuser-api-organization-shared</module>
<module>che-multiuser-api-organization</module>
<module>che-multiuser-api-remote-subscription</module>
<module>che-multiuser-api-workspace-activity</module>
</modules>
</project>
5 changes: 5 additions & 0 deletions pom.xml
Expand Up @@ -925,6 +925,11 @@
<artifactId>che-multiuser-api-resource-shared</artifactId>
<version>${che.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-api-workspace-activity</artifactId>
<version>${che.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.che.multiuser</groupId>
<artifactId>che-multiuser-keycloak-ide</artifactId>
Expand Down
Expand Up @@ -48,7 +48,7 @@ public class WorkspaceActivityManager {

private static final String ACTIVITY_CHECKER = "activity-checker";

private final long timeout;
private final long defaultTimeout;
private final WorkspaceActivityDao activityDao;
private final EventService eventService;
private final EventSubscriber<?> workspaceEventsSubscriber;
Expand All @@ -60,11 +60,11 @@ public WorkspaceActivityManager(
WorkspaceManager workspaceManager,
WorkspaceActivityDao activityDao,
EventService eventService,
@Named("che.workspace.agent.dev.inactive_stop_timeout_ms") long timeout) {
this.timeout = timeout > 0 ? timeout : -1;
@Named("che.limits.workspace.idle.timeout") long timeout) {
this.workspaceManager = workspaceManager;
this.eventService = eventService;
this.activityDao = activityDao;
this.defaultTimeout = timeout;
this.workspaceEventsSubscriber =
new EventSubscriber<WorkspaceStatusEvent>() {
@Override
Expand Down Expand Up @@ -104,15 +104,20 @@ public void onEvent(WorkspaceStatusEvent event) {
* @param activityTime moment in which the activity occurred
*/
public void update(String wsId, long activityTime) {
if (timeout > 0) {
try {
try {
long timeout = getIdleTimeout(wsId);
if (timeout > 0) {
activityDao.setExpiration(new WorkspaceExpiration(wsId, activityTime + timeout));
} catch (ServerException e) {
LOG.error(e.getLocalizedMessage(), e);
}
} catch (NotFoundException | ServerException e) {
LOG.error(e.getLocalizedMessage(), e);
}
}

protected long getIdleTimeout(String wsId) throws NotFoundException, ServerException {
return defaultTimeout;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have a test for this class?

}

@ScheduleDelay(
initialDelayParameterName = "che.workspace.activity_check_scheduler_delay_s",
delayParameterName = "che.workspace.activity_check_scheduler_period_s"
Expand Down