forked from I2P_Developers/i2p.i2p
consolidate maxMemory() calls
This commit is contained in:
@ -15,6 +15,7 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.NativeBigInteger;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Precalculate the Y and K for ElGamal encryption operations.
|
||||
@ -55,9 +56,7 @@ class YKGenerator {
|
||||
ctx = context;
|
||||
|
||||
// add to the defaults for every 128MB of RAM, up to 1GB
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 127*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
int factor = (int) Math.max(1l, Math.min(8l, 1 + (maxMemory / (128*1024*1024l))));
|
||||
int defaultMin = DEFAULT_YK_PRECALC_MIN * factor;
|
||||
int defaultMax = DEFAULT_YK_PRECALC_MAX * factor;
|
||||
|
@ -33,6 +33,7 @@ import net.i2p.crypto.SHA256Generator;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.OrderedProperties;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Defines the data that a router either publishes to the global routing table or
|
||||
@ -68,8 +69,7 @@ public class RouterInfo extends DatabaseEntry {
|
||||
/** should we cache the byte and string versions _byteified ? **/
|
||||
private boolean _shouldCache;
|
||||
/** maybe we should check if we are floodfill? */
|
||||
private static final boolean CACHE_ALL = Runtime.getRuntime().maxMemory() > 128*1024*1024l &&
|
||||
Runtime.getRuntime().maxMemory() < Long.MAX_VALUE;
|
||||
private static final boolean CACHE_ALL = SystemVersion.getMaxMemory() > 128*1024*1024l;
|
||||
|
||||
public static final String PROP_NETWORK_ID = "netId";
|
||||
public static final String PROP_CAPABILITIES = "caps";
|
||||
|
@ -11,6 +11,7 @@ import java.util.Map;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.LHMCache;
|
||||
import net.i2p.util.SimpleByteCache;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* A least recently used cache with a max size, for SimpleDataStructures.
|
||||
@ -49,9 +50,7 @@ public class SDSCache<V extends SimpleDataStructure> {
|
||||
private static final double MAX_FACTOR = 5.0;
|
||||
private static final double FACTOR;
|
||||
static {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
FACTOR = Math.max(MIN_FACTOR, Math.min(MAX_FACTOR, maxMemory / (128*1024*1024d)));
|
||||
}
|
||||
|
||||
|
@ -228,9 +228,7 @@ public abstract class Addresses {
|
||||
int size;
|
||||
I2PAppContext ctx = I2PAppContext.getCurrentContext();
|
||||
if (ctx != null && ctx.isRouterContext()) {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
long min = 128;
|
||||
long max = 4096;
|
||||
// 512 nominal for 128 MB
|
||||
|
@ -62,9 +62,7 @@ public final class ByteCache {
|
||||
*/
|
||||
private static final int MAX_CACHE;
|
||||
static {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
MAX_CACHE = (int) Math.min(4*1024*1024l, Math.max(128*1024l, maxMemory / 128));
|
||||
}
|
||||
|
||||
|
@ -58,9 +58,7 @@ public class SimpleScheduler {
|
||||
private SimpleScheduler(I2PAppContext context, String name) {
|
||||
_log = context.logManager().getLog(SimpleScheduler.class);
|
||||
_name = name;
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
_threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024))));
|
||||
_executor = new ScheduledThreadPoolExecutor(_threads, new CustomThreadFactory());
|
||||
_executor.prestartAllCoreThreads();
|
||||
|
@ -61,9 +61,7 @@ public class SimpleTimer {
|
||||
runner.setName(name);
|
||||
runner.setDaemon(true);
|
||||
runner.start();
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 128*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
int threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024))));
|
||||
for (int i = 1; i <= threads ; i++) {
|
||||
I2PThread executor = new I2PThread(new Executor(context, _log, _readyEvents, runn));
|
||||
|
@ -64,9 +64,7 @@ public class SimpleTimer2 {
|
||||
*/
|
||||
protected SimpleTimer2(I2PAppContext context, String name, boolean prestartAllThreads) {
|
||||
_name = name;
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
_threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024))));
|
||||
_executor = new CustomScheduledThreadPoolExecutor(_threads, new CustomThreadFactory());
|
||||
if (prestartAllThreads)
|
||||
|
@ -126,4 +126,16 @@ public abstract class SystemVersion {
|
||||
public static boolean hasWrapper() {
|
||||
return _hasWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime.getRuntime().maxMemory() but check for
|
||||
* bogus values
|
||||
* @since 0.9.8
|
||||
*/
|
||||
public static long getMaxMemory() {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory >= Long.MAX_VALUE / 2)
|
||||
maxMemory = 96*1024*1024l;
|
||||
return maxMemory;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import net.i2p.router.networkdb.kademlia.HandleFloodfillDatabaseLookupMessageJob
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Manage the pending jobs according to whatever algorithm is appropriate, giving
|
||||
@ -60,9 +61,7 @@ public class JobQueue {
|
||||
/** how many when we go parallel */
|
||||
private static final int RUNNERS;
|
||||
static {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 128*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
if (maxMemory < 64*1024*1024)
|
||||
RUNNERS = 3;
|
||||
else if (maxMemory < 256*1024*1024)
|
||||
|
@ -27,6 +27,7 @@ import net.i2p.router.tunnel.pool.TunnelPoolManager;
|
||||
import net.i2p.update.UpdateManager;
|
||||
import net.i2p.util.KeyRing;
|
||||
import net.i2p.util.I2PProperties.I2PPropertyCallback;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Build off the core I2P context to provide a root for a router instance to
|
||||
@ -114,9 +115,7 @@ public class RouterContext extends I2PAppContext {
|
||||
// and prng.bufferFillTime event count is ~30 per minute,
|
||||
// or about 2 seconds per buffer - so about 200x faster
|
||||
// to fill than to drain - so we don't need too many
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
long buffs = Math.min(16, Math.max(2, maxMemory / (14 * 1024 * 1024)));
|
||||
envProps.setProperty("prng.buffers", "" + buffs);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* The network database
|
||||
@ -417,9 +418,7 @@ public class FloodfillNetworkDatabaseFacade extends KademliaNetworkDatabaseFacad
|
||||
/** @since 0.8.7 */
|
||||
private static final int MAX_DB_BEFORE_SKIPPING_SEARCH;
|
||||
static {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 128*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
// 250 for every 32 MB, min of 250, max of 1250
|
||||
MAX_DB_BEFORE_SKIPPING_SEARCH = (int) Math.max(250l, Math.min(1250l, maxMemory / ((32 * 1024 * 1024l) / 250)));
|
||||
}
|
||||
|
@ -67,9 +67,7 @@ public abstract class TransportImpl implements Transport {
|
||||
private static final Map<Hash, byte[]> _IPMap;
|
||||
|
||||
static {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
long min = 512;
|
||||
long max = 4096;
|
||||
// 1024 nominal for 128 MB
|
||||
|
@ -26,6 +26,7 @@ import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.NativeBigInteger;
|
||||
import net.i2p.util.RandomSource;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Generate a new session key through a diffie hellman exchange. This uses the
|
||||
@ -458,9 +459,7 @@ public class DHSessionKeyBuilder {
|
||||
ctx.statManager().createRateStat("crypto.DHEmpty", "DH queue empty", "Encryption", new long[] { 60*60*1000 });
|
||||
|
||||
// add to the defaults for every 128MB of RAM, up to 512MB
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 127*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
int factor = (int) Math.max(1l, Math.min(4l, 1 + (maxMemory / (128*1024*1024l))));
|
||||
int defaultMin = DEFAULT_DH_PRECALC_MIN * factor;
|
||||
int defaultMax = DEFAULT_DH_PRECALC_MAX * factor;
|
||||
|
@ -29,6 +29,7 @@ import net.i2p.util.Addresses;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* The main NTCP NIO thread.
|
||||
@ -90,9 +91,7 @@ class EventPumper implements Runnable {
|
||||
private static final int MAX_MINB = 12;
|
||||
private static final int MIN_BUFS;
|
||||
static {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
MIN_BUFS = (int) Math.max(MIN_MINB, Math.min(MAX_MINB, 1 + (maxMemory / (16*1024*1024))));
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.HexDump;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Coordinate the connection to a single peer.
|
||||
@ -840,9 +841,7 @@ class NTCPConnection {
|
||||
private static final int MAX_BUFS = 16;
|
||||
private static int NUM_PREP_BUFS;
|
||||
static {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
NUM_PREP_BUFS = (int) Math.max(MIN_BUFS, Math.min(MAX_BUFS, 1 + (maxMemory / (16*1024*1024))));
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import java.util.concurrent.ThreadFactory;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.router.OutNetMessage;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Previously, NTCP was using SimpleTimer with a delay of 0, which
|
||||
@ -33,9 +34,7 @@ class NTCPSendFinisher {
|
||||
private ThreadPoolExecutor _executor;
|
||||
private static final int THREADS;
|
||||
static {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
THREADS = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024))));
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ import net.i2p.util.Addresses;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.OrderedProperties;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* The NIO TCP transport
|
||||
@ -571,9 +572,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
_finisher.start();
|
||||
_pumper.startPumping();
|
||||
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 128*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
int nr, nw;
|
||||
if (maxMemory < 32*1024*1024) {
|
||||
nr = nw = 1;
|
||||
|
@ -14,6 +14,7 @@ import net.i2p.router.util.CoDelBlockingQueue;
|
||||
import net.i2p.util.HexDump;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Pull fully completed fragments off the {@link InboundMessageFragments} queue,
|
||||
@ -41,9 +42,7 @@ class MessageReceiver {
|
||||
_log = ctx.logManager().getLog(MessageReceiver.class);
|
||||
_transport = transport;
|
||||
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
int qsize;
|
||||
if (maxMemory < 32*1024*1024) {
|
||||
_threadCount = 1;
|
||||
|
@ -12,6 +12,7 @@ import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.LHMCache;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Pull inbound packets from the inbound receiver's queue, figure out what
|
||||
@ -57,9 +58,7 @@ class PacketHandler {
|
||||
_introManager = introManager;
|
||||
_failCache = new LHMCache(24);
|
||||
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
int qsize = (int) Math.max(MIN_QUEUE_SIZE, Math.min(MAX_QUEUE_SIZE, maxMemory / (2*1024*1024)));
|
||||
_inboundQueue = new CoDelBlockingQueue(ctx, "UDP-Receiver", qsize);
|
||||
int num_handlers;
|
||||
|
@ -8,6 +8,7 @@ import net.i2p.data.Base64;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.util.LHMCache;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* basic helper to parse out peer info from a udp address
|
||||
@ -223,9 +224,7 @@ class UDPAddress {
|
||||
private static final Map<String, InetAddress> _inetAddressCache;
|
||||
|
||||
static {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
long min = 128;
|
||||
long max = 2048;
|
||||
// 512 nominal for 128 MB
|
||||
|
@ -12,6 +12,7 @@ import net.i2p.data.SessionKey;
|
||||
import net.i2p.router.util.CDQEntry;
|
||||
import net.i2p.util.Addresses;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Basic delivery unit containing the datagram. This also maintains a cache
|
||||
@ -48,9 +49,7 @@ class UDPPacket implements CDQEntry {
|
||||
private static final int MAX_CACHE_SIZE = 256;
|
||||
static {
|
||||
if (CACHE) {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
int csize = (int) Math.max(MIN_CACHE_SIZE, Math.min(MAX_CACHE_SIZE, maxMemory / (1024*1024)));
|
||||
_packetCache = new LinkedBlockingQueue(csize);
|
||||
} else {
|
||||
|
@ -10,6 +10,7 @@ import net.i2p.router.transport.FIFOBandwidthLimiter;
|
||||
import net.i2p.router.util.CoDelBlockingQueue;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Lowest level packet sender, pushes anything on its queue ASAP.
|
||||
@ -37,9 +38,7 @@ class UDPSender {
|
||||
_context = ctx;
|
||||
_dummy = false; // ctx.commSystem().isDummy();
|
||||
_log = ctx.logManager().getLog(UDPSender.class);
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
int qsize = (int) Math.max(MIN_QUEUE_SIZE, Math.min(MAX_QUEUE_SIZE, maxMemory / (1024*1024)));
|
||||
_outboundQueue = new CoDelBlockingQueue(ctx, "UDP-Sender", qsize);
|
||||
_socket = socket;
|
||||
|
@ -6,6 +6,7 @@ import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.util.DecayingBloomFilter;
|
||||
import net.i2p.router.util.DecayingHashSet;
|
||||
import net.i2p.util.SimpleByteCache;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Manage the IV validation for all of the router's tunnels by way of a big
|
||||
@ -38,9 +39,7 @@ class BloomFilterIVValidator implements IVValidator {
|
||||
// Note that at rates above 512KB, we increase the filter size
|
||||
// to keep acceptable false positive rates.
|
||||
// See DBF, BloomSHA1, and KeySelector for details.
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
if (_context.getBooleanProperty(PROP_FORCE))
|
||||
_filter = new DecayingBloomFilter(ctx, HALFLIFE_MS, 16, "TunnelIVV"); // 2MB fixed
|
||||
else if (KBps < MIN_SHARE_KBPS_TO_USE_BLOOM || maxMemory < MIN_MEM_TO_USE_BLOOM)
|
||||
|
@ -13,6 +13,7 @@ import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.SimpleScheduler;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Run through the tunnel gateways that have had messages added to them and push
|
||||
@ -45,9 +46,7 @@ class TunnelGatewayPumper implements Runnable {
|
||||
if (ctx.getBooleanProperty("i2p.dummyTunnelManager")) {
|
||||
_pumpers = 1;
|
||||
} else {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
_pumpers = (int) Math.max(MIN_PUMPERS, Math.min(MAX_PUMPERS, 1 + (maxMemory / (32*1024*1024))));
|
||||
}
|
||||
for (int i = 0; i < _pumpers; i++)
|
||||
|
Reference in New Issue
Block a user