From 0c07e0362956b6485d15584bc63a1441b87c5370 Mon Sep 17 00:00:00 2001 From: cristianpela Date: Mon, 17 May 2021 12:57:45 +0300 Subject: [PATCH 1/3] Moved self database from session to request scope. A new db connection is established on each http request and closed after the request has completed. This prevents "too many connections" exception from MySql to happen while too many users are logged in. --- .../selfxdsd/selfweb/SelfCoreComponent.java | 27 ++--- .../selfweb/SelfDatabaseComponent.java | 104 ++++++++++++++++++ 2 files changed, 116 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java diff --git a/src/main/java/com/selfxdsd/selfweb/SelfCoreComponent.java b/src/main/java/com/selfxdsd/selfweb/SelfCoreComponent.java index 332c8c6f..8972e268 100644 --- a/src/main/java/com/selfxdsd/selfweb/SelfCoreComponent.java +++ b/src/main/java/com/selfxdsd/selfweb/SelfCoreComponent.java @@ -22,11 +22,16 @@ */ package com.selfxdsd.selfweb; -import com.selfxdsd.api.*; -import com.selfxdsd.core.Env; +import com.selfxdsd.api.Contributors; +import com.selfxdsd.api.Login; +import com.selfxdsd.api.ProjectManagers; +import com.selfxdsd.api.Projects; +import com.selfxdsd.api.Self; +import com.selfxdsd.api.User; import com.selfxdsd.core.SelfCore; -import com.selfxdsd.storage.MySql; +import com.selfxdsd.storage.Database; import com.selfxdsd.storage.SelfJooq; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.SessionScope; @@ -47,19 +52,11 @@ public class SelfCoreComponent implements Self { /** * Default constructor for Spring. + * @param database Database connection. */ - public SelfCoreComponent() { - this( - new SelfCore( - new SelfJooq( - new MySql( - System.getenv(Env.DB_URL), - System.getenv(Env.DB_USER), - System.getenv(Env.DB_PASSWORD) - ) - ) - ) - ); + @Autowired + public SelfCoreComponent(final Database database) { + this.core = new SelfCore(new SelfJooq(database)); } /** diff --git a/src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java b/src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java new file mode 100644 index 00000000..b54049b2 --- /dev/null +++ b/src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2020-2021, Self XDSD Contributors + * All rights reserved. + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), + * to read the Software only. Permission is hereby NOT GRANTED to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software. + *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.selfxdsd.selfweb; + +import com.selfxdsd.core.Env; +import com.selfxdsd.storage.Database; +import com.selfxdsd.storage.MySql; +import org.jooq.DSLContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; + +import javax.servlet.http.HttpServletRequest; + +/** + * Self Database component. + * @author criske + * @version $Id$ + * @since 0.0.6 + */ +@Component +@RequestScope(proxyMode = ScopedProxyMode.INTERFACES) +public class SelfDatabaseComponent implements Database { + + /** + * Logger. + */ + private static final Logger LOG = LoggerFactory.getLogger( + SelfDatabaseComponent.class + ); + + /** + * Database delegate. + */ + private MySql delegate; + + /** + * Http request endpoint used for logging only. + */ + private final String requestEndpoint; + + /** + * Default constructor for Spring. + * @param request Http request endpoint used for logging. + */ + @Autowired + public SelfDatabaseComponent(final HttpServletRequest request) { + this.requestEndpoint = request.getRequestURL().toString(); + LOG.debug("Opening MySql connection for http request {} ...", + this.requestEndpoint); + delegate = new MySql( + System.getenv(Env.DB_URL), + System.getenv(Env.DB_USER), + System.getenv(Env.DB_PASSWORD) + ).connect(); + } + + @Override + public Database connect() { + this.delegate = this.delegate.connect(); + return this; + } + + @Override + public DSLContext jooq() { + return this.delegate.jooq(); + } + + @Override + public void close() { + LOG.debug("Http request {} has finished, closing MySql connection...", + this.requestEndpoint); + this.delegate.close(); + } + + @Override + public String dbms() { + return this.delegate.dbms(); + } + +} From 0bbdc485e630d3b9ec9231171bceb94aea15ed4b Mon Sep 17 00:00:00 2001 From: Pela Cristian Date: Tue, 18 May 2021 10:00:27 +0300 Subject: [PATCH 2/3] Updated version. --- src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java b/src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java index b54049b2..f86e4ca4 100644 --- a/src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java +++ b/src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java @@ -39,7 +39,7 @@ * Self Database component. * @author criske * @version $Id$ - * @since 0.0.6 + * @since 0.0.7 */ @Component @RequestScope(proxyMode = ScopedProxyMode.INTERFACES) From 67f23f109ea80ae1246f5e48ee2f7ff41e87217c Mon Sep 17 00:00:00 2001 From: cristianpela Date: Tue, 18 May 2021 11:16:16 +0300 Subject: [PATCH 3/3] #442 set proxy mode for default. --- src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java b/src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java index b54049b2..091eb38a 100644 --- a/src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java +++ b/src/main/java/com/selfxdsd/selfweb/SelfDatabaseComponent.java @@ -29,7 +29,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; @@ -42,7 +41,7 @@ * @since 0.0.6 */ @Component -@RequestScope(proxyMode = ScopedProxyMode.INTERFACES) +@RequestScope public class SelfDatabaseComponent implements Database { /**