diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/LoadDetectFilter.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/LoadDetectFilter.java index b8457be62e..272114a77e 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/LoadDetectFilter.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/LoadDetectFilter.java @@ -19,8 +19,6 @@ package com.baidu.hugegraph.api.filter; -import java.io.IOException; - import javax.inject.Singleton; import javax.ws.rs.ServiceUnavailableException; import javax.ws.rs.container.ContainerRequestContext; @@ -32,6 +30,7 @@ import com.baidu.hugegraph.config.HugeConfig; import com.baidu.hugegraph.config.ServerOptions; import com.baidu.hugegraph.core.WorkLoad; +import com.baidu.hugegraph.util.Bytes; @Provider @Singleton @@ -44,15 +43,30 @@ public class LoadDetectFilter implements ContainerRequestFilter { private javax.inject.Provider loadProvider; @Override - public void filter(ContainerRequestContext context) throws IOException { + public void filter(ContainerRequestContext context) { HugeConfig config = this.configProvider.get(); + long minFreeMemory = config.get(ServerOptions.MIN_FREE_MEMORY); + long allocatedMem = Runtime.getRuntime().totalMemory() - + Runtime.getRuntime().freeMemory(); + long presumableFreeMem = (Runtime.getRuntime().maxMemory() - + allocatedMem) / Bytes.MB; + if (presumableFreeMem < minFreeMemory) { + throw new ServiceUnavailableException(String.format( + "The server available memory %s(MB) is below than " + + "threshold %s(MB) and can't process the request, " + + "you can config %s to adjust it or try again later", + presumableFreeMem, minFreeMemory, + ServerOptions.MIN_FREE_MEMORY.name())); + } + int maxWorkerThreads = config.get(ServerOptions.MAX_WORKER_THREADS); WorkLoad load = this.loadProvider.get(); // There will be a thread doesn't work, dedicated to statistics if (load.incrementAndGet() >= maxWorkerThreads) { - throw new ServiceUnavailableException( + throw new ServiceUnavailableException(String.format( "The server is too busy to process the request, " + - "please try again later"); + "you can config %s to adjust it or try again later", + ServerOptions.MAX_WORKER_THREADS.name())); } } } diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/config/ServerOptions.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/config/ServerOptions.java index f7ac55b992..2753477343 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/config/ServerOptions.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/config/ServerOptions.java @@ -51,9 +51,20 @@ public static synchronized ServerOptions instance() { public static final ConfigOption MAX_WORKER_THREADS = new ConfigOption<>( "restserver.max_worker_threads", - "The maximum worker threads of rest server.", + "The maxmium worker threads of rest server.", positiveInt(), - 2 * Runtime.getRuntime().availableProcessors()); + 2 * Runtime.getRuntime().availableProcessors() + ); + + public static final ConfigOption MIN_FREE_MEMORY = + new ConfigOption<>( + "restserver.min_free_memory", + "The minmium free memory(MB) of rest server, requests " + + "will be rejected when the available memory of system " + + "is lower than this value.", + positiveInt(), + 256 + ); public static final ConfigOption GREMLIN_SERVER_URL = new ConfigOption<>( diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/UnitTestSuite.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/UnitTestSuite.java index 1ca55986f8..fc0e1109e2 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/UnitTestSuite.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/UnitTestSuite.java @@ -28,10 +28,12 @@ import com.baidu.hugegraph.unit.core.BackendMutationTest; import com.baidu.hugegraph.unit.core.CassandraTest; import com.baidu.hugegraph.unit.core.ConditionQueryFlattenTest; +import com.baidu.hugegraph.unit.core.DirectionsTest; import com.baidu.hugegraph.unit.core.EdgeIdTest; import com.baidu.hugegraph.unit.core.JsonUtilTest; -import com.baidu.hugegraph.unit.core.VersionTest; +import com.baidu.hugegraph.unit.core.SerialEnumTest; import com.baidu.hugegraph.unit.core.StringUtilTest; +import com.baidu.hugegraph.unit.core.VersionTest; import com.baidu.hugegraph.unit.rocksdb.RocksDBCountersTest; import com.baidu.hugegraph.unit.rocksdb.RocksDBSessionsTest; @@ -41,6 +43,8 @@ CacheManagerTest.class, VersionTest.class, + DirectionsTest.class, + SerialEnumTest.class, BackendMutationTest.class, CassandraTest.class, ConditionQueryFlattenTest.class, diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/core/DirectionsTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/core/DirectionsTest.java new file mode 100644 index 0000000000..2bb487afb1 --- /dev/null +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/core/DirectionsTest.java @@ -0,0 +1,81 @@ +/* + * + * * Copyright 2017 HugeGraph Authors + * * + * * Licensed to the Apache Software Foundation (ASF) under one or more + * * contributor license agreements. See the NOTICE file distributed with this + * * work for additional information regarding copyright ownership. The ASF + * * licenses this file to You under the Apache License, Version 2.0 (the + * * "License"); you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * * License for the specific language governing permissions and limitations + * * under the License. + * + */ + +package com.baidu.hugegraph.unit.core; + +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.junit.Test; + +import com.baidu.hugegraph.testutil.Assert; +import com.baidu.hugegraph.type.HugeType; +import com.baidu.hugegraph.type.define.Directions; + +public class DirectionsTest { + + @Test + public void testString() { + Assert.assertEquals("out", Directions.OUT.string()); + Assert.assertEquals("in", Directions.IN.string()); + Assert.assertEquals("both", Directions.BOTH.string()); + } + + @Test + public void testType() { + Assert.assertEquals(HugeType.EDGE_OUT, Directions.OUT.type()); + Assert.assertEquals(HugeType.EDGE_IN, Directions.IN.type()); + Assert.assertThrows(IllegalArgumentException.class, () -> { + Directions.BOTH.type(); + }); + } + + @Test + public void testFromHugeType() { + Assert.assertEquals(Directions.OUT, + Directions.convert(HugeType.EDGE_OUT)); + Assert.assertEquals(Directions.IN, + Directions.convert(HugeType.EDGE_IN)); + Assert.assertThrows(IllegalArgumentException.class, () -> { + Directions.convert(HugeType.EDGE); + }); + } + + @Test + public void testOpposite() { + Assert.assertEquals(Directions.IN, Directions.OUT.opposite()); + Assert.assertEquals(Directions.OUT, Directions.IN.opposite()); + Assert.assertEquals(Directions.BOTH, Directions.BOTH.opposite()); + } + + @Test + public void testToDirection() { + Assert.assertEquals(Direction.OUT, Directions.OUT.direction()); + Assert.assertEquals(Direction.IN, Directions.IN.direction()); + Assert.assertEquals(Direction.BOTH, Directions.BOTH.direction()); + } + + @Test + public void testFromDirection() { + Assert.assertEquals(Directions.OUT, Directions.convert(Direction.OUT)); + Assert.assertEquals(Directions.IN, Directions.convert(Direction.IN)); + Assert.assertEquals(Directions.BOTH, + Directions.convert(Direction.BOTH)); + } +} diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/core/SerialEnumTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/core/SerialEnumTest.java new file mode 100644 index 0000000000..9b9211a75e --- /dev/null +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/unit/core/SerialEnumTest.java @@ -0,0 +1,47 @@ +/* + * + * * Copyright 2017 HugeGraph Authors + * * + * * Licensed to the Apache Software Foundation (ASF) under one or more + * * contributor license agreements. See the NOTICE file distributed with this + * * work for additional information regarding copyright ownership. The ASF + * * licenses this file to You under the Apache License, Version 2.0 (the + * * "License"); you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * * License for the specific language governing permissions and limitations + * * under the License. + * + */ + +package com.baidu.hugegraph.unit.core; + +import org.junit.Test; + +import com.baidu.hugegraph.testutil.Assert; +import com.baidu.hugegraph.type.define.Cardinality; +import com.baidu.hugegraph.type.define.SerialEnum; + +public class SerialEnumTest { + + @Test + public void testRegister() { + SerialEnum.register(Cardinality.class); + Assert.assertTrue(SerialEnum.table.containsRow(Cardinality.class)); + } + + @Test + public void testFromCode() { + Assert.assertEquals(Cardinality.SINGLE, + SerialEnum.fromCode(Cardinality.class, (byte) 1)); + Assert.assertEquals(Cardinality.LIST, + SerialEnum.fromCode(Cardinality.class, (byte) 2)); + Assert.assertEquals(Cardinality.SET, + SerialEnum.fromCode(Cardinality.class, (byte) 3)); + } +}