fine tune for distributed setup

This commit is contained in:
anhefti 2021-11-10 10:00:50 +01:00
parent 780a17834c
commit 52b96647c1
6 changed files with 38 additions and 19 deletions

View file

@ -75,23 +75,25 @@ public class ProctorRoomConnectionsPopup {
.call()
.getOrThrow());
this.pageService.staticListTableBuilder(connections, EntityType.CLIENT_CONNECTION)
final EntityTable<ClientConnection> compose =
this.pageService.staticListTableBuilder(connections, EntityType.CLIENT_CONNECTION)
.withEmptyMessage(EMPTY_LIST_TEXT_KEY)
.withPaging(10)
.withEmptyMessage(EMPTY_LIST_TEXT_KEY)
.withPaging(10)
.withColumn(new ColumnDefinition<>(
Domain.CLIENT_CONNECTION.ATTR_EXAM_USER_SESSION_ID,
TABLE_COLUMN_NAME,
ClientConnection::getUserSessionId))
.withColumn(new ColumnDefinition<>(
Domain.CLIENT_CONNECTION.ATTR_EXAM_USER_SESSION_ID,
TABLE_COLUMN_NAME,
ClientConnection::getUserSessionId))
.withDefaultAction(t -> actionBuilder
.newAction(ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION)
.withParentEntityKey(parentEntityKey)
.withExec(action -> showClientConnection(action, dialog, t))
.create())
.withDefaultAction(t -> actionBuilder
.newAction(ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION)
.withParentEntityKey(parentEntityKey)
.withExec(action -> showClientConnection(action, dialog, t))
.create())
.compose(pageContext);
.compose(pageContext);
compose.reset();
}
private PageAction showClientConnection(

View file

@ -106,8 +106,17 @@ public class StaticListPageSupplier<T> implements PageSupplier<T> {
if (numOfPages <= 0) {
return new Page<>(1, 1, this.column, this.list);
}
final List<T> subList = this.list.subList(this.pageNumber * this.pageSize,
this.pageNumber * this.pageSize + this.pageSize);
int from = (this.pageNumber - 1) * this.pageSize;
if (from < 0) {
from = 0;
}
int to = (this.pageNumber - 1) * this.pageSize + this.pageSize;
if (to >= this.list.size()) {
to = this.list.size();
}
final List<T> subList = this.list.subList(from, to);
return new Page<>(numOfPages, this.pageNumber, this.column, subList);
});
}

View file

@ -21,6 +21,7 @@ import org.joda.time.DateTimeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Component;
@ -52,13 +53,14 @@ public class DistributedPingCache implements DisposableBean {
final ClientEventLastPingMapper clientEventLastPingMapper,
final ClientEventRecordMapper clientEventRecordMapper,
final WebserviceInfo webserviceInfo,
final TaskScheduler taskScheduler) {
final TaskScheduler taskScheduler,
@Value("${sebserver.webservice.distributed.pingUpdate:3000}") final long pingUpdate) {
this.clientEventLastPingMapper = clientEventLastPingMapper;
this.clientEventRecordMapper = clientEventRecordMapper;
if (webserviceInfo.isDistributed()) {
try {
this.taskRef = taskScheduler.scheduleAtFixedRate(this::updateCache, 1000);
this.taskRef = taskScheduler.scheduleAtFixedRate(this::updateCache, pingUpdate);
} catch (final Exception e) {
log.error("Failed to initialize distributed ping cache update task");
this.taskRef = null;
@ -127,7 +129,6 @@ public class DistributedPingCache implements DisposableBean {
}
}
@Transactional
public void updatePing(final Long pingRecordId, final Long pingTime) {
try {
@ -156,6 +157,8 @@ public class DistributedPingCache implements DisposableBean {
} catch (final Exception e) {
log.error("Failed to delete ping for connection -> {}", connectionId, e);
} finally {
this.pingCache.remove(connectionId);
}
}

View file

@ -13,6 +13,7 @@ spring.datasource.hikari.initializationFailTimeout=30000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
spring.datasource.hikari.maximumPoolSize=500
sebserver.http.client.connect-timeout=15000
sebserver.http.client.connection-request-timeout=10000

View file

@ -25,7 +25,7 @@ sebserver.gui.entrypoint=/gui
sebserver.gui.webservice.apipath=${sebserver.webservice.api.admin.endpoint}
# defines the polling interval that is used to poll the webservice for client connection data on a monitored exam page
sebserver.gui.webservice.poll-interval=1000
sebserver.gui.webservice.poll-interval=3000
sebserver.gui.webservice.mock-lms-enabled=true
sebserver.gui.webservice.edx-lms-enabled=true
sebserver.gui.webservice.moodle-lms-enabled=true

View file

@ -10,6 +10,9 @@ sebserver.init.adminaccount.username=sebserver-admin
sebserver.init.database.integrity.checks=true
sebserver.init.database.integrity.try-fix=true
sebserver.webservice.distributed=false
sebserver.webservice.distributed.pingUpdate=3000
### webservice caching
spring.cache.jcache.provider=org.ehcache.jsr107.EhcacheCachingProvider
spring.cache.jcache.config=classpath:config/ehcache.xml
@ -28,6 +31,7 @@ spring.datasource.hikari.initializationFailTimeout=3000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
spring.datasource.hikari.maximumPoolSize=500
### webservice security
spring.datasource.password=${sebserver.mariadb.password}