Unverified Commit 90b82cb5 authored by David Kocher's avatar David Kocher
Browse files

Extract interface for client cache to allow custom implementations. See #37...


Extract interface for client cache to allow custom implementations. See #37 for reasons of possible other lax implementations with non expiring client leases.
Signed-off-by: default avatarDavid Kocher <dkocher@iterate.ch>
parent 15d38f26
/*
* Copyright (c) 2020 iterate GmbH
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program (see the file COPYING.LIB for more
* details); if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.dcache.nfs.v4;
import org.dcache.nfs.v4.xdr.clientid4;
import java.util.stream.Stream;
public interface ClientCache {
/**
* Cache client by id
*
* @param clientid4 Client id
* @param nfs4Client Client reference
*/
void put(clientid4 clientid4, NFS4Client nfs4Client);
/**
* @param clientid4 Client id
* @return Cached client or null if not found
*/
NFS4Client get(clientid4 clientid4);
/**
* Remove client by id
*
* @param clientid4 Client id
* @return Previously cached client if any
*/
NFS4Client remove(clientid4 clientid4);
/**
* Check and remove expired entries.
*/
void cleanUp();
/**
* @return Return cached clients and update last access time for elements retrieved.
*/
Stream<NFS4Client> stream();
/**
* @return Return cached clients. The last access time of the element will not be updated.
*/
Stream<NFS4Client> peek();
}
/*
* Copyright (c) 2020 iterate GmbH
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program (see the file COPYING.LIB for more
* details); if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.dcache.nfs.v4;
import org.dcache.nfs.util.Cache;
import org.dcache.nfs.util.CacheElement;
import org.dcache.nfs.util.CacheEventListener;
import org.dcache.nfs.v4.xdr.clientid4;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
public class DefaultClientCache extends Cache<clientid4, NFS4Client> implements ClientCache {
public DefaultClientCache(int leaseTime, CacheEventListener<clientid4, NFS4Client> eventListener) {
super("NFSv41 clients", 5000, Long.MAX_VALUE,
TimeUnit.SECONDS.toMillis(leaseTime * 2),
eventListener);
}
@Override
public Stream<NFS4Client> stream() {
return entries().stream()
.map(CacheElement::getObject);
}
@Override
public Stream<NFS4Client> peek() {
return entries().stream()
.map(CacheElement::peekObject);
}
}
......@@ -45,7 +45,6 @@ import org.dcache.nfs.v4.xdr.stateid4;
import org.dcache.nfs.v4.xdr.verifier4;
import org.dcache.oncrpc4j.util.Bytes;
import org.dcache.nfs.util.Cache;
import org.dcache.nfs.util.CacheElement;
import org.dcache.nfs.util.NopCacheEventListener;
import static com.google.common.base.Preconditions.checkState;
......@@ -65,7 +64,7 @@ public class NFSv4StateHandler {
private final AtomicInteger _clientId = new AtomicInteger(0);
// mapping between server generated clietid and nfs_client_id, not confirmed yet
private final Cache<clientid4, NFS4Client> _clientsByServerId;
private final ClientCache _clientsByServerId;
/**
* Client's lease expiration time in seconds.
......@@ -101,10 +100,12 @@ public class NFSv4StateHandler {
* @param clientStore store used by state handler to keep track of valid clients.
*/
public NFSv4StateHandler(int leaseTime, int instanceId, ClientRecoveryStore clientStore) {
this(leaseTime, instanceId, clientStore, new DefaultClientCache(leaseTime, new DeadClientCollector(clientStore)));
}
public NFSv4StateHandler(int leaseTime, int instanceId, ClientRecoveryStore clientStore, ClientCache clientsByServerId) {
_leaseTime = leaseTime;
_clientsByServerId = new Cache<>("NFSv41 clients", 5000, Long.MAX_VALUE,
TimeUnit.SECONDS.toMillis(_leaseTime * 2),
new DeadClientCollector());
_clientsByServerId = clientsByServerId;
_running = true;
_instanceId = instanceId;
......@@ -230,9 +231,8 @@ public class NFSv4StateHandler {
* @return an existing client record or null, if not matching record found.
*/
public synchronized NFS4Client clientByOwner(byte[] ownerid) {
return _clientsByServerId.entries()
return _clientsByServerId
.stream()
.map(CacheElement::getObject)
.filter(c -> Arrays.equals(c.getOwnerId(), ownerid))
.findAny()
.orElse(null);
......@@ -254,8 +254,7 @@ public class NFSv4StateHandler {
public synchronized List<NFS4Client> getClients() {
checkState(_running, "NFS state handler not running");
return _clientsByServerId.entries().stream()
.map(CacheElement::peekObject)
return _clientsByServerId.peek()
.collect(Collectors.toList());
}
......@@ -276,7 +275,12 @@ public class NFSv4StateHandler {
return _openFileTracker;
}
private class DeadClientCollector extends NopCacheEventListener<clientid4, NFS4Client> {
private static final class DeadClientCollector extends NopCacheEventListener<clientid4, NFS4Client> {
private final ClientRecoveryStore clientStore;
private DeadClientCollector(ClientRecoveryStore clientStore) {
this.clientStore = clientStore;
}
@Override
public void notifyExpired(Cache<clientid4, NFS4Client> cache, NFS4Client client) {
......@@ -312,8 +316,7 @@ public class NFSv4StateHandler {
}
private synchronized void drainClients() {
_clientsByServerId.entries().stream()
.map(CacheElement::getObject)
_clientsByServerId.stream()
.forEach(c -> {
c.tryDispose();
_clientsByServerId.remove(c.getId());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment