Implement backoff retry for gcloud session data store; fix gcloud session module
This commit is contained in:
parent
d5fca6ee22
commit
86eedd3ad8
|
@ -5,13 +5,15 @@
|
|||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Configure a factory for GCloudSessionStores -->
|
||||
<!-- Configure a factory for GCloudSessionDataStores -->
|
||||
<!-- ===================================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.session.GCloudSessionStoreFactory">
|
||||
<Set name="gcloudConfiguration"><Ref id="gconf"/></Set>
|
||||
<Set name="gracePeriod"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
|
||||
<New class="org.eclipse.jetty.gcloud.session.GCloudSessionDataStoreFactory">
|
||||
<Set name="gCloudConfiguration"><Ref id="gconf"/></Set>
|
||||
<Set name="gracePeriodSec"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
|
||||
<Set name="maxRetries"><Property name="jetty.gcloudSession.maxRetries" default="5"/></Set>
|
||||
<Set name="backoffMs"><Property name="jetty.gcloudSession.backoffMs" default="50"/></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
|
|
@ -48,7 +48,7 @@ lib/jetty-gcloud-session-manager-${jetty.version}.jar
|
|||
lib/gcloud/*.jar
|
||||
|
||||
[xml]
|
||||
sessions/gcloud/session-store.xml
|
||||
etc/sessions/gcloud/session-store.xml
|
||||
|
||||
[license]
|
||||
GCloudDatastore is an open source project hosted on Github and released under the Apache 2.0 license.
|
||||
|
@ -61,6 +61,8 @@ type=remote
|
|||
[ini-template]
|
||||
|
||||
## GCloudDatastore Session config
|
||||
#jetty.gcloudSession.maxRetries=
|
||||
#jetty.gcloudSession.backoffMs=
|
||||
|
||||
|
||||
## Remote datastore
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.gcloud.session;
|
|||
|
||||
import com.google.gcloud.datastore.Blob;
|
||||
import com.google.gcloud.datastore.Datastore;
|
||||
import com.google.gcloud.datastore.DatastoreException;
|
||||
import com.google.gcloud.datastore.DatastoreFactory;
|
||||
import com.google.gcloud.datastore.Entity;
|
||||
import com.google.gcloud.datastore.Key;
|
||||
|
@ -45,6 +46,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
|
||||
import org.eclipse.jetty.server.session.SessionContext;
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
import org.eclipse.jetty.server.session.UnwriteableSessionDataException;
|
||||
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -73,16 +75,40 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
public static final String KIND = "GCloudSession";
|
||||
public static final int DEFAULT_MAX_QUERY_RESULTS = 100;
|
||||
public static final int DEFAULT_MAX_RETRIES = 5;
|
||||
public static final int DEFAULT_BACKOFF_MS = 50;
|
||||
|
||||
private GCloudConfiguration _config;
|
||||
private Datastore _datastore;
|
||||
private KeyFactory _keyFactory;
|
||||
private int _maxResults = DEFAULT_MAX_QUERY_RESULTS;
|
||||
private int _maxRetries = DEFAULT_MAX_RETRIES;
|
||||
private int _backoff = DEFAULT_BACKOFF_MS;
|
||||
|
||||
|
||||
|
||||
public void setBackoffMs (int ms)
|
||||
{
|
||||
_backoff = ms;
|
||||
}
|
||||
|
||||
|
||||
public int getBackoffMs ()
|
||||
{
|
||||
return _backoff;
|
||||
}
|
||||
|
||||
|
||||
public void setMaxRetries (int retries)
|
||||
{
|
||||
_maxRetries = retries;
|
||||
}
|
||||
|
||||
|
||||
public int getMaxRetries ()
|
||||
{
|
||||
return _maxRetries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStart()
|
||||
|
@ -296,10 +322,43 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
|
||||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Writing session {} to DataStore", data.getId());
|
||||
|
||||
//TODO implement backoff strategy
|
||||
|
||||
Entity entity = entityFromSession(data, makeKey(id, _context));
|
||||
_datastore.put(entity);
|
||||
|
||||
//attempt the update with exponential back-off
|
||||
int backoff = getBackoffMs();
|
||||
int attempts;
|
||||
for (attempts = 0; attempts < getMaxRetries(); attempts++)
|
||||
{
|
||||
try
|
||||
{
|
||||
_datastore.put(entity);
|
||||
return;
|
||||
}
|
||||
catch (DatastoreException e)
|
||||
{
|
||||
if (e.code().retryable())
|
||||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Datastore put retry {} waiting {}ms", attempts, backoff);
|
||||
|
||||
try
|
||||
{
|
||||
Thread.currentThread().sleep(backoff);
|
||||
}
|
||||
catch (InterruptedException x)
|
||||
{
|
||||
}
|
||||
backoff *= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//retries have been exceeded
|
||||
throw new UnwriteableSessionDataException(id, _context, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.gcloud.session;
|
||||
|
||||
import org.eclipse.jetty.server.session.AbstractSessionDataStoreFactory;
|
||||
import org.eclipse.jetty.server.session.SessionDataStore;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
|
||||
/**
|
||||
* GCloudSessionDataStoreFactory
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class GCloudSessionDataStoreFactory extends AbstractSessionDataStoreFactory
|
||||
{
|
||||
private GCloudConfiguration _config;
|
||||
private int _maxRetries;
|
||||
private int _backoffMs;
|
||||
|
||||
|
||||
public GCloudConfiguration getGCloudConfiguration()
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
public void setGCloudConfiguration(GCloudConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public int getMaxRetries()
|
||||
{
|
||||
return _maxRetries;
|
||||
}
|
||||
|
||||
public void setMaxRetries(int maxRetries)
|
||||
{
|
||||
_maxRetries = maxRetries;
|
||||
}
|
||||
|
||||
public int getBackoffMs()
|
||||
{
|
||||
return _backoffMs;
|
||||
}
|
||||
|
||||
public void setBackoffMs(int backoffMs)
|
||||
{
|
||||
_backoffMs = backoffMs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler)
|
||||
*/
|
||||
@Override
|
||||
public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception
|
||||
{
|
||||
GCloudSessionDataStore ds = new GCloudSessionDataStore();
|
||||
ds.setGCloudConfiguration(getGCloudConfiguration());
|
||||
ds.setBackoffMs(getBackoffMs());
|
||||
ds.setMaxRetries(getMaxRetries());
|
||||
ds.setGracePeriodSec(getGracePeriodSec());
|
||||
return ds;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue