diff --git a/http-service/pom.xml b/http-service/pom.xml index 7883c40bec..a402bb6872 100644 --- a/http-service/pom.xml +++ b/http-service/pom.xml @@ -105,6 +105,12 @@ redis.clients jedis 2.10.0 + + + org.apache.commons + commons-pool2 + + diff --git a/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java b/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java index 4d422897a8..f81e3cd3e1 100644 --- a/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java +++ b/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java @@ -54,17 +54,12 @@ import org.springframework.scheduling.annotation.EnableScheduling; import org.sql2o.Sql2o; import org.sql2o.converters.Converter; import org.sql2o.quirks.NoQuirks; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; @SpringBootApplication @EnableScheduling @Slf4j public class SpringBootWebApplication extends SpringBootServletInitializer { - @Value("${redis.host:localhost}") - private String redisHost; - @Bean protected ServletContextListener listener() { @@ -135,12 +130,6 @@ public class SpringBootWebApplication extends SpringBootServletInitializer return new Sql2o(dataSource, new NoQuirks(converters)); } - @Bean - JedisPool jedis() - { - return new JedisPool(new JedisPoolConfig(), redisHost); - } - @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { diff --git a/http-service/src/main/java/net/runelite/http/service/account/AccountService.java b/http-service/src/main/java/net/runelite/http/service/account/AccountService.java index 263e1b1290..e31ada89aa 100644 --- a/http-service/src/main/java/net/runelite/http/service/account/AccountService.java +++ b/http-service/src/main/java/net/runelite/http/service/account/AccountService.java @@ -44,6 +44,7 @@ import net.runelite.http.api.ws.WebsocketMessage; import net.runelite.http.api.ws.messages.LoginResponse; import net.runelite.http.service.account.beans.SessionEntry; import net.runelite.http.service.account.beans.UserEntry; +import net.runelite.http.service.util.redis.RedisPool; import net.runelite.http.service.ws.SessionManager; import net.runelite.http.service.ws.WSService; import org.slf4j.Logger; @@ -58,7 +59,6 @@ import org.sql2o.Connection; import org.sql2o.Sql2o; import org.sql2o.Sql2oException; import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; @RestController @RequestMapping("/account") @@ -98,7 +98,7 @@ public class AccountService private final String oauthClientId; private final String oauthClientSecret; private final AuthFilter auth; - private final JedisPool jedisPool; + private final RedisPool jedisPool; @Autowired public AccountService( @@ -106,7 +106,7 @@ public class AccountService @Value("${oauth.client-id}") String oauthClientId, @Value("${oauth.client-secret}") String oauthClientSecret, AuthFilter auth, - JedisPool jedisPool + RedisPool jedisPool ) { this.sql2o = sql2o; diff --git a/http-service/src/main/java/net/runelite/http/service/chat/ChatService.java b/http-service/src/main/java/net/runelite/http/service/chat/ChatService.java index b8f4955f28..71b3d9a2c3 100644 --- a/http-service/src/main/java/net/runelite/http/service/chat/ChatService.java +++ b/http-service/src/main/java/net/runelite/http/service/chat/ChatService.java @@ -25,20 +25,20 @@ package net.runelite.http.service.chat; import java.time.Duration; +import net.runelite.http.service.util.redis.RedisPool; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; @Service public class ChatService { private static final Duration EXPIRE = Duration.ofMinutes(2); - private final JedisPool jedisPool; + private final RedisPool jedisPool; @Autowired - public ChatService(JedisPool jedisPool) + public ChatService(RedisPool jedisPool) { this.jedisPool = jedisPool; } diff --git a/http-service/src/main/java/net/runelite/http/service/util/redis/RedisPool.java b/http-service/src/main/java/net/runelite/http/service/util/redis/RedisPool.java new file mode 100644 index 0000000000..a69232ed55 --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/util/redis/RedisPool.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 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 OWNER 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 net.runelite.http.service.util.redis; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import redis.clients.jedis.Jedis; + +@Component +public class RedisPool +{ + private final BlockingQueue queue; + + RedisPool(@Value("${redis.pool.size:10}") int queueSize, @Value("${redis.host:localhost}") String redisHost) + { + queue = new ArrayBlockingQueue<>(queueSize); + for (int i = 0; i < queueSize; ++i) + { + Jedis jedis = new PooledJedis(redisHost); + queue.offer(jedis); + } + } + + public Jedis getResource() + { + Jedis jedis; + try + { + jedis = queue.poll(1, TimeUnit.SECONDS); + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + if (jedis == null) + { + throw new RuntimeException("Unable to acquire connection from pool, timeout"); + } + return jedis; + } + + class PooledJedis extends Jedis + { + PooledJedis(String host) + { + super(host); + } + + @Override + public void close() + { + queue.offer(this); + } + } +}