http service: replace JedisPool with own pool implementation

JedisPool appears to not work correctly and is losing connections.
This commit is contained in:
Adam
2019-01-15 09:40:29 -05:00
parent a47c63e931
commit c50023eb89
5 changed files with 92 additions and 17 deletions

View File

@@ -105,6 +105,12 @@
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.10.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* 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<Jedis> 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);
}
}
}