1
0
Fork 0

Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel

This commit is contained in:
Michael Hackstein 2014-02-21 20:59:31 +01:00
commit 6020b914b8
45 changed files with 375 additions and 235 deletions

View File

@ -176,19 +176,26 @@ advantage that you can use auto-completion.
------------------------------------- Help ------------------------------------- ------------------------------------- Help -------------------------------------
Predefined objects: Predefined objects:
arango: ArangoConnection arango: ArangoConnection
db: ArangoDatabase db: ArangoDatabase
fm: FoxxManager
Example: Example:
> db._collections(); list all collections > db._collections(); list all collections
> db._create(<coll_name>); create a new collection > db._create(<name>) create a new collection
> db._drop(<coll_name>); drop a collection > db._drop(<name>) drop a collection
> db.<coll_name>.all(); list all documents > db.<name>.toArray() list all documents
> id = db.<coll_name>.save({ ... }); save a document > id = db.<name>.save({ ... }) save a document
> db.<coll_name>.remove(<_id>); delete a document > db.<name>.remove(<_id>) delete a document
> db.<coll_name>.document(<_id>); get a document > db.<name>.document(<_id>) retrieve a document
> help show help pages > db.<name>.replace(<_id>, {...}) overwrite a document
> helpQueries query help > db.<name>.update(<_id>, {...}) partially update a document
> exit > db.<name>.exists(<_id>) check if document exists
> db._query(<query>).toArray() execute an AQL query
> db._useDatabase(<name>) switch database
> db._createDatabase(<name>) create a new database
> db._listDatabases() list existing databases
> help show help pages
> exit
arangosh> arangosh>
This gives you a prompt, where you can issue JavaScript commands. This gives you a prompt, where you can issue JavaScript commands.
@ -273,10 +280,7 @@ Querying For Documents {#FirstStepsArangoDBQuerying}
---------------------------------------------------- ----------------------------------------------------
All documents are stored in collections. All collections are stored in a All documents are stored in collections. All collections are stored in a
database. The database object is accessible there the variable `db` from database. The database object is accessible via the variable `db`.
the module
arangosh> var db = require("org/arangodb").db;
Creating a collection is simple. You can use the `_create` method Creating a collection is simple. You can use the `_create` method
of the `db` variable. of the `db` variable.

View File

@ -55,6 +55,11 @@ using namespace std;
BOOST_CHECK_EQUAL(expected, e->FEATURE_NAME(feature)()); \ BOOST_CHECK_EQUAL(expected, e->FEATURE_NAME(feature)()); \
DELETE_ENDPOINT(e); DELETE_ENDPOINT(e);
#define CHECK_ENDPOINT_SERVER_FEATURE(type, specification, feature, expected) \
e = Endpoint::serverFactory(specification, 1, true); \
BOOST_CHECK_EQUAL(expected, e->FEATURE_NAME(feature)()); \
DELETE_ENDPOINT(e);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- setup / tear-down // --SECTION-- setup / tear-down
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -121,8 +126,9 @@ BOOST_AUTO_TEST_CASE (EndpointSpecification) {
CHECK_ENDPOINT_FEATURE(client, "tcp://localhost", Specification, "tcp://localhost"); CHECK_ENDPOINT_FEATURE(client, "tcp://localhost", Specification, "tcp://localhost");
CHECK_ENDPOINT_FEATURE(client, "SSL://127.0.0.5", Specification, "SSL://127.0.0.5"); CHECK_ENDPOINT_FEATURE(client, "SSL://127.0.0.5", Specification, "SSL://127.0.0.5");
CHECK_ENDPOINT_FEATURE(client, "httP@ssl://localhost:4635", Specification, "httP@ssl://localhost:4635"); CHECK_ENDPOINT_FEATURE(client, "httP@ssl://localhost:4635", Specification, "httP@ssl://localhost:4635");
CHECK_ENDPOINT_FEATURE(server, "unix:///path/to/socket", Specification, "unix:///path/to/socket");
CHECK_ENDPOINT_FEATURE(server, "htTp@UNIx:///a/b/c/d/e/f.s", Specification, "htTp@UNIx:///a/b/c/d/e/f.s"); CHECK_ENDPOINT_SERVER_FEATURE(server, "unix:///path/to/socket", Specification, "unix:///path/to/socket");
CHECK_ENDPOINT_SERVER_FEATURE(server, "htTp@UNIx:///a/b/c/d/e/f.s", Specification, "htTp@UNIx:///a/b/c/d/e/f.s");
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -138,11 +144,11 @@ BOOST_AUTO_TEST_CASE (EndpointTypes) {
CHECK_ENDPOINT_FEATURE(client, "ssl://localhost", Type, Endpoint::ENDPOINT_CLIENT); CHECK_ENDPOINT_FEATURE(client, "ssl://localhost", Type, Endpoint::ENDPOINT_CLIENT);
CHECK_ENDPOINT_FEATURE(client, "unix:///path/to/socket", Type, Endpoint::ENDPOINT_CLIENT); CHECK_ENDPOINT_FEATURE(client, "unix:///path/to/socket", Type, Endpoint::ENDPOINT_CLIENT);
CHECK_ENDPOINT_FEATURE(server, "tcp://127.0.0.1", Type, Endpoint::ENDPOINT_SERVER); CHECK_ENDPOINT_SERVER_FEATURE(server, "tcp://127.0.0.1", Type, Endpoint::ENDPOINT_SERVER);
CHECK_ENDPOINT_FEATURE(server, "tcp://localhost", Type, Endpoint::ENDPOINT_SERVER); CHECK_ENDPOINT_SERVER_FEATURE(server, "tcp://localhost", Type, Endpoint::ENDPOINT_SERVER);
CHECK_ENDPOINT_FEATURE(server, "ssl://127.0.0.1", Type, Endpoint::ENDPOINT_SERVER); CHECK_ENDPOINT_SERVER_FEATURE(server, "ssl://127.0.0.1", Type, Endpoint::ENDPOINT_SERVER);
CHECK_ENDPOINT_FEATURE(server, "ssl://localhost", Type, Endpoint::ENDPOINT_SERVER); CHECK_ENDPOINT_SERVER_FEATURE(server, "ssl://localhost", Type, Endpoint::ENDPOINT_SERVER);
CHECK_ENDPOINT_FEATURE(server, "unix:///path/to/socket", Type, Endpoint::ENDPOINT_SERVER); CHECK_ENDPOINT_SERVER_FEATURE(server, "unix:///path/to/socket", Type, Endpoint::ENDPOINT_SERVER);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -460,7 +466,7 @@ BOOST_AUTO_TEST_CASE (EndpointHostString) {
BOOST_AUTO_TEST_CASE (EndpointIsConnectedServer1) { BOOST_AUTO_TEST_CASE (EndpointIsConnectedServer1) {
Endpoint* e; Endpoint* e;
e = Endpoint::serverFactory("tcp://127.0.0.1"); e = Endpoint::serverFactory("tcp://127.0.0.1", 1, true);
BOOST_CHECK_EQUAL(false, e->isConnected()); BOOST_CHECK_EQUAL(false, e->isConnected());
DELETE_ENDPOINT(e); DELETE_ENDPOINT(e);
} }
@ -472,7 +478,7 @@ BOOST_AUTO_TEST_CASE (EndpointIsConnectedServer1) {
BOOST_AUTO_TEST_CASE (EndpointIsConnectedServer2) { BOOST_AUTO_TEST_CASE (EndpointIsConnectedServer2) {
Endpoint* e; Endpoint* e;
e = Endpoint::serverFactory("ssl://127.0.0.1"); e = Endpoint::serverFactory("ssl://127.0.0.1", 1, true);
BOOST_CHECK_EQUAL(false, e->isConnected()); BOOST_CHECK_EQUAL(false, e->isConnected());
DELETE_ENDPOINT(e); DELETE_ENDPOINT(e);
} }
@ -484,7 +490,7 @@ BOOST_AUTO_TEST_CASE (EndpointIsConnectedServer2) {
BOOST_AUTO_TEST_CASE (EndpointIsConnectedServer3) { BOOST_AUTO_TEST_CASE (EndpointIsConnectedServer3) {
Endpoint* e; Endpoint* e;
e = Endpoint::serverFactory("unix:///tmp/socket"); e = Endpoint::serverFactory("unix:///tmp/socket", 1, true);
BOOST_CHECK_EQUAL(false, e->isConnected()); BOOST_CHECK_EQUAL(false, e->isConnected());
DELETE_ENDPOINT(e); DELETE_ENDPOINT(e);
} }
@ -532,7 +538,7 @@ BOOST_AUTO_TEST_CASE (EndpointIsConnectedClient3) {
BOOST_AUTO_TEST_CASE (EndpointServerTcpIpv4WithPort) { BOOST_AUTO_TEST_CASE (EndpointServerTcpIpv4WithPort) {
Endpoint* e; Endpoint* e;
e = Endpoint::serverFactory("tcp://127.0.0.1:667"); e = Endpoint::serverFactory("tcp://127.0.0.1:667", 1, true);
BOOST_CHECK_EQUAL("tcp://127.0.0.1:667", e->getSpecification()); BOOST_CHECK_EQUAL("tcp://127.0.0.1:667", e->getSpecification());
BOOST_CHECK_EQUAL(Endpoint::ENDPOINT_SERVER, e->getType()); BOOST_CHECK_EQUAL(Endpoint::ENDPOINT_SERVER, e->getType());
BOOST_CHECK_EQUAL(Endpoint::DOMAIN_IPV4, e->getDomainType()); BOOST_CHECK_EQUAL(Endpoint::DOMAIN_IPV4, e->getDomainType());
@ -552,7 +558,7 @@ BOOST_AUTO_TEST_CASE (EndpointServerTcpIpv4WithPort) {
BOOST_AUTO_TEST_CASE (EndpointServerUnix) { BOOST_AUTO_TEST_CASE (EndpointServerUnix) {
Endpoint* e; Endpoint* e;
e = Endpoint::serverFactory("unix:///path/to/arango.sock"); e = Endpoint::serverFactory("unix:///path/to/arango.sock", 1, true);
BOOST_CHECK_EQUAL("unix:///path/to/arango.sock", e->getSpecification()); BOOST_CHECK_EQUAL("unix:///path/to/arango.sock", e->getSpecification());
BOOST_CHECK_EQUAL(Endpoint::ENDPOINT_SERVER, e->getType()); BOOST_CHECK_EQUAL(Endpoint::ENDPOINT_SERVER, e->getType());
BOOST_CHECK_EQUAL(Endpoint::DOMAIN_UNIX, e->getDomainType()); BOOST_CHECK_EQUAL(Endpoint::DOMAIN_UNIX, e->getDomainType());

View File

@ -893,14 +893,8 @@ static v8::Handle<v8::Value> JS_ExecuteGlobalContextFunction (v8::Arguments cons
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> JS_DefinePeriodic (v8::Arguments const& argv) { static v8::Handle<v8::Value> JS_DefinePeriodic (v8::Arguments const& argv) {
v8::Isolate* isolate;
TRI_v8_global_t* v8g;
v8::HandleScope scope; v8::HandleScope scope;
isolate = v8::Isolate::GetCurrent();
v8g = (TRI_v8_global_t*) isolate->GetData();
if (argv.Length() != 5) { if (argv.Length() != 5) {
TRI_V8_EXCEPTION_USAGE(scope, "definePeriodic(<offset>, <period>, <module>, <funcname>, <string-parameter>)"); TRI_V8_EXCEPTION_USAGE(scope, "definePeriodic(<offset>, <period>, <module>, <funcname>, <string-parameter>)");
} }

View File

@ -1,4 +1,4 @@
# AragoDB configuration file # ArangoDB configuration file
# #
# Documentation: # Documentation:
# http://www.arangodb.org/manuals/current/CommandLine.html # http://www.arangodb.org/manuals/current/CommandLine.html

View File

@ -7,6 +7,7 @@
disable-authentication = true disable-authentication = true
endpoint = tcp://localhost:8529 endpoint = tcp://localhost:8529
threads = 5 threads = 5
reuse-address = true
[scheduler] [scheduler]
threads = 3 threads = 3

View File

@ -151,3 +151,11 @@ table.dataTable thead th {
#saveDocumentButton { #saveDocumentButton {
margin-top: 5px; margin-top: 5px;
} }
#showSaveState {
display:none;
color: green;
float:right;
margin-top: 10px;
font-weight: 300;
}

View File

@ -9,6 +9,8 @@
</div> </div>
<div class="usermenu" id="userBar" style="float:right;"> <div class="usermenu" id="userBar" style="float:right;">
</div> </div>
<div class="notificationmenu" id="notificationBar" style="float:right;">
</div>
<div class="navmenu" id="navigationBar"> <div class="navmenu" id="navigationBar">
</div> </div>
</div> </div>

View File

@ -72,7 +72,8 @@
this.footerView = new window.FooterView(); this.footerView = new window.FooterView();
this.naviView = new window.NavigationView({ this.naviView = new window.NavigationView({
notificationCollection: this.notificationList notificationCollection: this.notificationList,
userCollection: window.userCollection
}); });
this.footerView.render(); this.footerView.render();
this.naviView.render(); this.naviView.render();

View File

@ -1,4 +1,4 @@
<script id="addGraphView.ejs" type="text/template"> <script id="addNewGraphView.ejs" type="text/template">
<div id="add-graph" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display:none"> <div id="add-graph" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display:none">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>

View File

@ -23,24 +23,24 @@
<ul> <ul>
<li class="nav-header">Type</li> <li class="nav-header">Type</li>
<li><a href="#"> <li><a>
<label class="checkbox checkboxLabel"> <label class="checkbox checkboxLabel">
<input class="css-checkbox" type="checkbox" id="checkSystem"> <input class="css-checkbox" type="checkbox" id="checkSystem">
<label class="css-label"></label>System <label class="css-label" id="checkSystem"></label>System
</label> </label>
</a></li> </a></li>
<li><a href="#"> <li><a>
<label class="checkbox checkboxLabel"> <label class="checkbox checkboxLabel">
<input class="css-checkbox" type="checkbox" id="checkDocument"> <input class="css-checkbox" type="checkbox" id="checkDocument">
<label class="css-label"></label>Document <label class="css-label" id="checkDocument"></label>Document
</label> </label>
</a></li> </a></li>
<li><a href="#"> <li><a>
<label class="checkbox checkboxLabel"> <label class="checkbox checkboxLabel">
<input class="css-checkbox" type="checkbox" id="checkEdge"> <input class="css-checkbox" type="checkbox" id="checkEdge">
<label class="css-label"></label>Edge <label class="css-label" id="checkEdge"></label>Edge
</label> </label>
</a></li> </a></li>
</ul> </ul>

View File

@ -1,5 +1,5 @@
<script id="dbSelectionView.ejs" type="text/template"> <script id="dbSelectionView.ejs" type="text/template">
<a href="#" class="tab" id="dbselection">DB: <%=current%> <b class="caret"></b></a> <a href="#" class="tab" id="dbselection"></span><div class="dbselection">DB: <%=current%></div> <b class="caret"></b></a>
<ul class="link-dropdown-menu" id="dbs_dropdown"> <ul class="link-dropdown-menu" id="dbs_dropdown">
<% <%
if (list.length > 1) { if (list.length > 1) {
@ -13,7 +13,7 @@ if (list.length > 1) {
} }
%> %>
<li class="dropdown-item"> <li class="dropdown-item">
<a id=<%=i%> class="dbSelectionLink" href="#"><%=i%></a> <a id=<%=i%> class="dbSelectionLink tab" href="#"><%=i%></a>
</li> </li>
<% <%
}); });
@ -23,7 +23,9 @@ if (list.length > 1) {
%> %>
<% if (current === "_system") { %> <% if (current === "_system") { %>
<li class="dropdown-header">Manager</li> <li class="dropdown-header">Manager</li>
<li id="databaseNavi" class="dropdown-item"><a id="databases" class="" href="#databases">Manage DBs</a></li> <li id="databaseNavi" class="dropdown-item">
<a id="databases" class="tab" href="#databases">Manage DBs</a>
</li>
<% } %> <% } %>
</ul> </ul>
</script> </script>

View File

@ -8,6 +8,7 @@
<div id="tableDiv"> <div id="tableDiv">
<div id="documentEditor"></div> <div id="documentEditor"></div>
<button id="saveDocumentButton" class="btn btn-success pull-right">Save</button> <button id="saveDocumentButton" class="btn btn-success pull-right">Save</button>
<div id="showSaveState">Saved...</div>
</div> </div>
</div> </div>

View File

@ -5,10 +5,12 @@
<li id="dbSelect" class="dropdown databases-menu"></li> <li id="dbSelect" class="dropdown databases-menu"></li>
<li class="collections-menu"><a id="collections" class="tab" href="#collections">Collections</a></li> <li class="collections-menu"><a id="collections" class="tab" href="#collections">Collections</a></li>
<li class="graphviewer-menu"><a id="graph" class="tab" href="#graph">Graphs</a></li> <li class="graphviewer-menu"><a id="graph" class="tab" href="#graph">Graphs</a></li>
<li class="applications-menu navbar-spacer"><a id="applications" class="tab" href="#applications">Applications</a></li> <li class="navbar-spacer big"></li>
<li class="applications-menu">
<a id="applications" class="tab" href="#applications">Applications</a>
</li>
<li class="query-menu"><a id="query" class="tab" href="#query">AQL Editor</a></li> <li class="query-menu"><a id="query" class="tab" href="#query">AQL Editor</a></li>
<!-- <li class="api-menu"><a id="api" class="tab" href="#api">API</a></li> --> <li class="dropdown tools-menu navbar-spacer-med" id="toolsDropdown">
<li class="dropdown tools-menu" id="toolsDropdown">
<a href="#" class="tab" id="tools">Tools <b class="caret"></b></a> <a href="#" class="tab" id="tools">Tools <b class="caret"></b></a>
<ul class="link-dropdown-menu" id="tools_dropdown"> <ul class="link-dropdown-menu" id="tools_dropdown">
<li class="dropdown-header">Tools</li> <li class="dropdown-header">Tools</li>
@ -23,8 +25,12 @@
<li class="dropdown-item"> <li class="dropdown-item">
<a id="api" class="internalLink" href="#api">API</a> <a id="api" class="internalLink" href="#api">API</a>
</li> </li>
<li class="dropdown-item">
<a id="userManagement" class="internalLink" href="#api">User Management</a>
</li>
</ul> </ul>
</li> </li>
<li class="navbar-spacer med"></li>
<li class="dropdown" id="linkDropdown"> <li class="dropdown" id="linkDropdown">
<a href="#" class="tab" id="links">Links <b class="caret"></b></a> <a href="#" class="tab" id="links">Links <b class="caret"></b></a>
<ul class="link-dropdown-menu" id="link_dropdown"> <ul class="link-dropdown-menu" id="link_dropdown">

View File

@ -0,0 +1,17 @@
<script id="notificationView.ejs" type="text/template">
<ul class="navlist" id="notificationViewUl">
<div class="navlogo">
<div id="stat_hd" class="notificationButton"><a id="stat_hd_counter">0</a></div>
</div>
<li class="dropdown">
<ul class="user-dropdown-menu fixedDropdown" id="notification_menu">
<li class="dropdown-header"><a>Notifications</a></li>
<ul class="innerDropdownInnerUL"></ul>
<button id="removeAllNotifications" class="btn btn-danger">Clear</button>
</ul>
</li>
</ul>
</script>

View File

@ -1,10 +1,6 @@
<script id="userBarView.ejs" type="text/template"> <script id="userBarView.ejs" type="text/template">
<ul class="navlist" id="userBarUl"> <ul class="navlist" id="userBarUl">
<div class="navlogo">
<div id="stat_hd" class="notificationButton"><a id="stat_hd_counter">0</a></div>
</div>
<li class="dropdown user-menu userImg"> <li class="dropdown user-menu userImg">
<a href="#" class="tab userImg" id="user" > <a href="#" class="tab userImg" id="user" >
<img class="userMenuImg" src="<%=img%>" id="userimage" /> <b class="caret"></b> <img class="userMenuImg" src="<%=img%>" id="userimage" /> <b class="caret"></b>
@ -12,43 +8,19 @@
<ul class="user-dropdown-menu" id="user_dropdown"> <ul class="user-dropdown-menu" id="user_dropdown">
<li class="dropdown-header" style="text-transform: none"> <li class="dropdown-header" style="text-transform: none">
<% <%
if(username === null) { if (name) {%>
%>User Management<%
} else {
if (name) {%>
<%=name%> (<%=username%>) <%=name%> (<%=username%>)
<% } else {%> <% } else {%>
<%=username%> <%=username%>
<%} <% } %>
}
%>
<% if(username !== null) { %>
<li class="dropdown-item"> <li class="dropdown-item">
<a id="userProfile" class="tab" href="#user">User profile</a> <a id="userProfile" class="tab" href="#user">User profile</a>
</li> </li>
<% } %>
<li class="dropdown-item">
<a id="userManagement" class="internalLink" href="#userManagement">User management</a>
</li>
<% if(username !== null) { %>
<li class="dropdown-item"> <li class="dropdown-item">
<a id="userLogout" class="tab" href="#user">Logout</a> <a id="userLogout" class="tab" href="#user">Logout</a>
</li> </li>
<% } %>
</ul> </ul>
</li> </li>
<li class="dropdown">
<ul class="user-dropdown-menu fixedDropdown" id="notification_menu">
<li class="dropdown-header"><a>Notifications</a></li>
<ul class="innerDropdownInnerUL"></ul>
<button id="removeAllNotifications" class="btn btn-danger">Clear</button>
</ul>
</li>
</ul> </ul>
</script> </script>

View File

@ -75,13 +75,20 @@
"click #sortName" : "sortName", "click #sortName" : "sortName",
"click #sortType" : "sortType", "click #sortType" : "sortType",
"click #sortOrder" : "sortOrder", "click #sortOrder" : "sortOrder",
"click #collectionsToggle" : "toggleView" "click #collectionsToggle" : "toggleView",
"click .css-label" : "checkBoxes"
}, },
toggleView: function() { toggleView: function() {
$('#collectionsDropdown2').slideToggle(200); $('#collectionsDropdown2').slideToggle(200);
}, },
checkBoxes: function (e) {
//chrome bugfix
var clicked = e.currentTarget.id;
$('#'+clicked).click();
},
checkSystem: function () { checkSystem: function () {
var searchOptions = this.collection.searchOptions; var searchOptions = this.collection.searchOptions;
var oldValue = searchOptions.includeSystem; var oldValue = searchOptions.includeSystem;
@ -188,7 +195,6 @@
}, },
resetSearch: function () { resetSearch: function () {
console.log("resetSearch");
if (this.searchTimeout) { if (this.searchTimeout) {
clearTimeout(this.searchTimeout); clearTimeout(this.searchTimeout);
this.searchTimeout = null; this.searchTimeout = null;
@ -199,8 +205,6 @@
}, },
restrictToSearchPhraseKey: function (e) { restrictToSearchPhraseKey: function (e) {
this.currentSearchString =
console.log("restrictToSearchPhraseKey");
// key pressed in search box // key pressed in search box
var self = this; var self = this;

View File

@ -18,8 +18,7 @@
}, },
changeDatabase: function(e) { changeDatabase: function(e) {
// var changeTo = $(".dbSelectionLink > option:selected").attr("id"); var changeTo = $(e.currentTarget).closest(".dbSelectionLink.tab").attr("id");
var changeTo = $(".dbSelectionLink").attr("id");
var url = this.collection.createDatabaseURL(changeTo); var url = this.collection.createDatabaseURL(changeTo);
window.location.replace(url); window.location.replace(url);
}, },

View File

@ -80,6 +80,10 @@
return; return;
} }
} }
if (result === true) {
$('#showSaveState').fadeIn(1000).fadeOut(1000);
}
}, },
breadcrumb: function () { breadcrumb: function () {

View File

@ -14,14 +14,17 @@
}, },
initialize: function () { initialize: function () {
this.userCollection = this.options.userCollection,
this.dbSelectionView = new window.DBSelectionView({ this.dbSelectionView = new window.DBSelectionView({
collection: window.arangoDatabase, collection: window.arangoDatabase,
current: window.currentDB current: window.currentDB
}); });
this.userBarView = new window.UserBarView({ this.userBarView = new window.UserBarView({
collection: this.options.notificationCollection,
userCollection: window.userCollection userCollection: window.userCollection
}); });
this.notificationView = new window.NotificationView({
collection: this.options.notificationCollection,
});
this.statisticBarView = new window.StatisticBarView({}); this.statisticBarView = new window.StatisticBarView({});
}, },
@ -29,7 +32,6 @@
this.dbSelectionView.render($("#dbSelect")); this.dbSelectionView.render($("#dbSelect"));
}, },
template: templateEngine.createTemplate("navigationView.ejs"), template: templateEngine.createTemplate("navigationView.ejs"),
render: function () { render: function () {
@ -37,7 +39,10 @@
isSystem: window.currentDB.get("isSystem") isSystem: window.currentDB.get("isSystem")
})); }));
this.dbSelectionView.render($("#dbSelect")); this.dbSelectionView.render($("#dbSelect"));
this.userBarView.render(); this.notificationView.render($("#notificationBar"));
if (this.userCollection.whoAmI() !== null) {
this.userBarView.render();
}
this.statisticBarView.render($("#statisticBar")); this.statisticBarView.render($("#statisticBar"));
return this; return this;
}, },

View File

@ -0,0 +1,69 @@
/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true */
/*global Backbone, templateEngine, $, window*/
(function () {
"use strict";
window.NotificationView = Backbone.View.extend({
events: {
"click .navlogo #stat_hd" : "toggleNotification",
"click .notificationItem .fa" : "removeNotification",
"click #removeAllNotifications" : "removeAllNotifications"
},
initialize: function () {
this.collection.bind("add", this.renderNotifications.bind(this));
this.collection.bind("remove", this.renderNotifications.bind(this));
this.collection.bind("reset", this.renderNotifications.bind(this));
},
notificationItem: templateEngine.createTemplate("notificationItem.ejs"),
el: '#notificationBar',
template: templateEngine.createTemplate("notificationView.ejs"),
toggleNotification: function (e) {
var counter = this.collection.length;
if (counter !== 0) {
$('#notification_menu').toggle();
}
},
removeAllNotifications: function () {
this.collection.reset();
$('#notification_menu').hide();
},
removeNotification: function(e) {
var cid = e.target.id;
this.collection.get(cid).destroy();
},
renderNotifications: function() {
$('#stat_hd_counter').text(this.collection.length);
if (this.collection.length === 0) {
$('#stat_hd').removeClass('fullNotification');
$('#notification_menu').hide();
}
else {
$('#stat_hd').addClass('fullNotification');
}
$('.innerDropdownInnerUL').html(this.notificationItem.render({
notifications : this.collection
}));
},
render: function () {
$(this.el).html(this.template.render({
notifications : this.collection
}));
this.renderNotifications();
this.delegateEvents();
return this.el;
}
});
}());

View File

@ -10,23 +10,15 @@
"click .tab" : "navigateByTab", "click .tab" : "navigateByTab",
"mouseenter .dropdown" : "showDropdown", "mouseenter .dropdown" : "showDropdown",
"mouseleave .dropdown" : "hideDropdown", "mouseleave .dropdown" : "hideDropdown",
"click .navlogo #stat_hd" : "toggleNotification",
"click .notificationItem .fa" : "removeNotification",
"click #removeAllNotifications" : "removeAllNotifications",
"click #userLogout" : "userLogout" "click #userLogout" : "userLogout"
}, },
initialize: function () { initialize: function () {
this.collection.bind("add", this.renderNotifications.bind(this));
this.collection.bind("remove", this.renderNotifications.bind(this));
this.collection.bind("reset", this.renderNotifications.bind(this));
this.userCollection = this.options.userCollection; this.userCollection = this.options.userCollection;
this.userCollection.fetch({async:false}); this.userCollection.fetch({async:false});
this.userCollection.bind("change:extra", this.render.bind(this)); this.userCollection.bind("change:extra", this.render.bind(this));
}, },
notificationItem: templateEngine.createTemplate("notificationItem.ejs"),
template: templateEngine.createTemplate("userBarView.ejs"), template: templateEngine.createTemplate("userBarView.ejs"),
navigateBySelect: function () { navigateBySelect: function () {
@ -47,10 +39,6 @@
e.preventDefault(); e.preventDefault();
}, },
toggleNotification: function (e) {
$('#notification_menu').toggle();
},
showDropdown: function (e) { showDropdown: function (e) {
var tab = e.target || e.srcElement; var tab = e.target || e.srcElement;
var navigateTo = tab.id; var navigateTo = tab.id;
@ -64,31 +52,7 @@
$("#user_dropdown").hide(); $("#user_dropdown").hide();
}, },
removeAllNotifications: function () { render: function (el) {
this.collection.reset();
},
removeNotification: function(e) {
var cid = e.target.id;
this.collection.get(cid).destroy();
},
renderNotifications: function() {
$('#stat_hd_counter').text(this.collection.length);
if (this.collection.length === 0) {
$('#stat_hd').removeClass('fullNotification');
}
else {
$('#stat_hd').addClass('fullNotification');
}
$('.innerDropdownInnerUL').html(this.notificationItem.render({
notifications : this.collection
}));
},
render: function () {
var username = this.userCollection.whoAmI(), var username = this.userCollection.whoAmI(),
img = null, img = null,
name = null, name = null,
@ -115,10 +79,8 @@
img : img, img : img,
name : name, name : name,
username : username, username : username,
active : active, active : active
notifications : this.collection
})); }));
this.renderNotifications();
this.delegateEvents(); this.delegateEvents();
return this.$el; return this.$el;

View File

@ -0,0 +1,8 @@
.dbselection {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
max-width: 160px;
float: left;
margin-right: 3px;
}

View File

@ -1,7 +1,7 @@
nav.navbar { nav.navbar {
@extend %fixedbar; @extend %fixedbar;
top: 0px; top: 0px;
height: 37px; height: 38px;
margin-bottom: 3px; margin-bottom: 3px;
} }
@ -21,6 +21,23 @@ ul.navlist {
li { li {
@extend %pull-left; @extend %pull-left;
margin-left: 1px; margin-left: 1px;
&.navbar-spacer {
width: 1px;
height: 28px;
margin-top: 5px;
background-color: $c_white;
&.big {
margin-left: 10px;
margin-right: 10px;
}
&.med {
margin-left: 5px;
margin-right: 5px;
}
&:hover {
background-color: $c_white;
}
}
} }
> li.active, > li.active,
li.dropdown-item:hover, li.dropdown-item:hover,
@ -34,13 +51,13 @@ ul.navlist {
a.tab { a.tab {
padding: { padding: {
top: 8px; top: 9px;
left: 10px; left: 10px;
bottom: 10px; bottom: 10px;
right: 10px; right: 10px;
} }
&.userImg { &.userImg {
padding-bottom: 4px; padding-bottom: 5px;
} }
color: $c_white; color: $c_white;
display: block; display: block;
@ -72,7 +89,3 @@ ul.user-dropdown-menu {
border-left: 5px solid transparent; border-left: 5px solid transparent;
content: ""; content: "";
} }
.navbar-spacer {
margin-right: 15px;
}

View File

@ -1,5 +1,5 @@
.fixedDropdown { .fixedDropdown {
margin: 34px 0 0 0 !important; margin: 37px 0 0 0 !important;
border-radius: 0 !important; border-radius: 0 !important;
width: 210px; width: 210px;
} }
@ -22,9 +22,12 @@
} }
.fixedDropdown .notificationItemContent { .fixedDropdown .notificationItemContent {
width: 160px; width: 155px;
float: left; float: left;
margin-left: 15px; margin-left: 15px;
max-width: 155px;
white-space: normal;
word-wrap: break-word;
} }
.fixedDropdown button { .fixedDropdown button {
@ -62,7 +65,7 @@
float: left; float: left;
font-size: 20px; font-size: 20px;
position: relative; position: relative;
right: 8px; right: 4px;
top: -9px; top: -9px;
} }
@ -84,7 +87,7 @@
font-weight: 300; font-weight: 300;
} }
#stat_hd:hover { .fullNotification:hover {
cursor:pointer; cursor:pointer;
} }

View File

@ -0,0 +1,7 @@
.tooltip-inner {
max-width: 300px !important;
word-wrap: break-word !important;
white-space: normal !important;
}

View File

@ -1,8 +1,8 @@
.userMenuImg { .userMenuImg {
height : "26"; // height : 26px;
width : "26"; // width : 26px;
background-color: #333232; background-color: #333232;
border-radius: 3px; border-radius: 3px;
border: 2px solid #8AA051; border: 2px solid #8AA051;
margin-top: -3px; margin-top: -4px;
} }

View File

@ -285,7 +285,7 @@ ul.arangoPagination a {
nav.navbar { nav.navbar {
top: 0px; top: 0px;
height: 37px; height: 38px;
margin-bottom: 3px; } margin-bottom: 3px; }
div.navlogo { div.navlogo {
@ -297,6 +297,19 @@ ul.navlist {
list-style: none; } list-style: none; }
ul.navlist li { ul.navlist li {
margin-left: 1px; } margin-left: 1px; }
ul.navlist li.navbar-spacer {
width: 1px;
height: 28px;
margin-top: 5px;
background-color: white; }
ul.navlist li.navbar-spacer.big {
margin-left: 10px;
margin-right: 10px; }
ul.navlist li.navbar-spacer.med {
margin-left: 5px;
margin-right: 5px; }
ul.navlist li.navbar-spacer:hover {
background-color: white; }
ul.navlist > li.active, ul.navlist > li.active,
ul.navlist li.dropdown-item:hover, ul.navlist li.dropdown-item:hover,
ul.navlist > li:hover { ul.navlist > li:hover {
@ -305,14 +318,14 @@ ul.navlist {
margin-left: 0px; } margin-left: 0px; }
a.tab { a.tab {
padding-top: 8px; padding-top: 9px;
padding-left: 10px; padding-left: 10px;
padding-bottom: 10px; padding-bottom: 10px;
padding-right: 10px; padding-right: 10px;
color: white; color: white;
display: block; } display: block; }
a.tab.userImg { a.tab.userImg {
padding-bottom: 4px; } padding-bottom: 5px; }
#arangoCollectionSelect { #arangoCollectionSelect {
display: none; display: none;
@ -331,9 +344,6 @@ a.tab {
border-left: 5px solid transparent; border-left: 5px solid transparent;
content: ""; } content: ""; }
.navbar-spacer {
margin-right: 15px; }
footer.footer { footer.footer {
bottom: 0px; bottom: 0px;
height: 40px; } height: 40px; }
@ -418,7 +428,7 @@ li.tile {
right: 0px; } right: 0px; }
.fixedDropdown { .fixedDropdown {
margin: 34px 0 0 0 !important; margin: 37px 0 0 0 !important;
border-radius: 0 !important; border-radius: 0 !important;
width: 210px; } width: 210px; }
@ -436,9 +446,12 @@ li.tile {
padding-left: 5px !important; } padding-left: 5px !important; }
.fixedDropdown .notificationItemContent { .fixedDropdown .notificationItemContent {
width: 160px; width: 155px;
float: left; float: left;
margin-left: 15px; } margin-left: 15px;
max-width: 155px;
white-space: normal;
word-wrap: break-word; }
.fixedDropdown button { .fixedDropdown button {
float: right; float: right;
@ -467,7 +480,7 @@ li.tile {
float: left; float: left;
font-size: 20px; font-size: 20px;
position: relative; position: relative;
right: 8px; right: 4px;
top: -9px; } top: -9px; }
.notificationItem i:hover { .notificationItem i:hover {
@ -485,7 +498,7 @@ li.tile {
.notificationItemContent { .notificationItemContent {
font-weight: 300; } font-weight: 300; }
#stat_hd:hover { .fullNotification:hover {
cursor: pointer; } cursor: pointer; }
.fullNotification { .fullNotification {
@ -593,9 +606,20 @@ select.filterSelect {
margin-left: 10px !important; } margin-left: 10px !important; }
.userMenuImg { .userMenuImg {
height: "26";
width: "26";
background-color: #333232; background-color: #333232;
border-radius: 3px; border-radius: 3px;
border: 2px solid #8AA051; border: 2px solid #8AA051;
margin-top: -3px; } margin-top: -4px; }
.tooltip-inner {
max-width: 300px !important;
word-wrap: break-word !important;
white-space: normal !important; }
.dbselection {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
max-width: 160px;
float: left;
margin-right: 3px; }

View File

@ -26,3 +26,7 @@
@import "dropdowns"; @import "dropdowns";
// Dropdown menu // Dropdown menu
@import "userMenu"; @import "userMenu";
// Tooltips
@import "tooltips";
// dbSelection
@import "dbSelection";

View File

@ -43,6 +43,8 @@ var internal = require("internal");
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
exports.historian = function (param) { exports.historian = function (param) {
"use strict";
try { try {
var result = {}; var result = {};

View File

@ -100,6 +100,7 @@ ApplicationEndpointServer::ApplicationEndpointServer (ApplicationServer* applica
_endpointList(), _endpointList(),
_httpPort(), _httpPort(),
_endpoints(), _endpoints(),
_reuseAddress(true),
_keepAliveTimeout(300.0), _keepAliveTimeout(300.0),
_defaultApiCompatibility(0), _defaultApiCompatibility(0),
_allowMethodOverride(false), _allowMethodOverride(false),
@ -213,6 +214,7 @@ void ApplicationEndpointServer::setupOptions (map<string, ProgramOptionsDescript
// issue #175: add deprecated hidden option for downwards compatibility // issue #175: add deprecated hidden option for downwards compatibility
options[ApplicationServer::OPTIONS_HIDDEN] options[ApplicationServer::OPTIONS_HIDDEN]
("server.http-port", &_httpPort, "http port for client requests (deprecated)") ("server.http-port", &_httpPort, "http port for client requests (deprecated)")
("server.reuse-address", "try to reuse address")
; ;
options[ApplicationServer::OPTIONS_SERVER] options[ApplicationServer::OPTIONS_SERVER]
@ -224,6 +226,7 @@ void ApplicationEndpointServer::setupOptions (map<string, ProgramOptionsDescript
("server.backlog-size", &_backlogSize, "listen backlog size") ("server.backlog-size", &_backlogSize, "listen backlog size")
("server.default-api-compatibility", &_defaultApiCompatibility, "default API compatibility version (e.g. 10300)") ("server.default-api-compatibility", &_defaultApiCompatibility, "default API compatibility version (e.g. 10300)")
("server.keep-alive-timeout", &_keepAliveTimeout, "keep-alive timeout in seconds") ("server.keep-alive-timeout", &_keepAliveTimeout, "keep-alive timeout in seconds")
("server.no-reuse-address", "do not try to reuse address")
; ;
options[ApplicationServer::OPTIONS_SSL] options[ApplicationServer::OPTIONS_SSL]
@ -247,6 +250,15 @@ bool ApplicationEndpointServer::parsePhase2 (ProgramOptions& options) {
if (! ok) { if (! ok) {
return false; return false;
} }
// check if want to reuse the address
if (options.has("server.reuse-address")) {
_reuseAddress = true;
}
if (options.has("server.no-reuse-address")) {
_reuseAddress = false;
}
if (_backlogSize <= 0 || _backlogSize > SOMAXCONN) { if (_backlogSize <= 0 || _backlogSize > SOMAXCONN) {
LOG_FATAL_AND_EXIT("invalid value for --server.backlog-size. maximum allowed value is %d", (int) SOMAXCONN); LOG_FATAL_AND_EXIT("invalid value for --server.backlog-size. maximum allowed value is %d", (int) SOMAXCONN);
@ -262,7 +274,7 @@ bool ApplicationEndpointServer::parsePhase2 (ProgramOptions& options) {
// add & validate endpoints // add & validate endpoints
for (vector<string>::const_iterator i = _endpoints.begin(); i != _endpoints.end(); ++i) { for (vector<string>::const_iterator i = _endpoints.begin(); i != _endpoints.end(); ++i) {
bool ok = _endpointList.add((*i), dbNames, _backlogSize); bool ok = _endpointList.add((*i), dbNames, _backlogSize, _reuseAddress);
if (! ok) { if (! ok) {
LOG_FATAL_AND_EXIT("invalid endpoint '%s'", (*i).c_str()); LOG_FATAL_AND_EXIT("invalid endpoint '%s'", (*i).c_str());
@ -325,7 +337,7 @@ bool ApplicationEndpointServer::addEndpoint (std::string const& newEndpoint,
WRITE_LOCKER(_endpointsLock); WRITE_LOCKER(_endpointsLock);
Endpoint* endpoint; Endpoint* endpoint;
bool ok = _endpointList.add(newEndpoint, dbNames, _backlogSize, &endpoint); bool ok = _endpointList.add(newEndpoint, dbNames, _backlogSize, _reuseAddress, &endpoint);
if (! ok) { if (! ok) {
return false; return false;
@ -474,7 +486,7 @@ bool ApplicationEndpointServer::loadEndpoints () {
std::map<std::string, std::vector<std::string> >::const_iterator it; std::map<std::string, std::vector<std::string> >::const_iterator it;
for (it = endpoints.begin(); it != endpoints.end(); ++it) { for (it = endpoints.begin(); it != endpoints.end(); ++it) {
bool ok = _endpointList.add((*it).first, (*it).second, _backlogSize); bool ok = _endpointList.add((*it).first, (*it).second, _backlogSize, _reuseAddress);
if (! ok) { if (! ok) {
return false; return false;

View File

@ -390,6 +390,12 @@ namespace triagens {
vector<string> _endpoints; vector<string> _endpoints;
////////////////////////////////////////////////////////////////////////////////
/// @brief try to reuse address
////////////////////////////////////////////////////////////////////////////////
bool _reuseAddress;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief timeout for HTTP keep-alive /// @brief timeout for HTTP keep-alive
/// ///

View File

@ -182,15 +182,17 @@ std::string Endpoint::getUnifiedForm (const std::string& specification) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Endpoint* Endpoint::clientFactory (const std::string& specification) { Endpoint* Endpoint::clientFactory (const std::string& specification) {
return Endpoint::factory(ENDPOINT_CLIENT, specification, 0); return Endpoint::factory(ENDPOINT_CLIENT, specification, 0, false);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief create a server endpoint object from a string value /// @brief create a server endpoint object from a string value
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Endpoint* Endpoint::serverFactory (const std::string& specification, int listenBacklog) { Endpoint* Endpoint::serverFactory (const std::string& specification,
return Endpoint::factory(ENDPOINT_SERVER, specification, listenBacklog); int listenBacklog,
bool reuseAddress) {
return Endpoint::factory(ENDPOINT_SERVER, specification, listenBacklog, reuseAddress);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -199,7 +201,8 @@ Endpoint* Endpoint::serverFactory (const std::string& specification, int listenB
Endpoint* Endpoint::factory (const Endpoint::EndpointType type, Endpoint* Endpoint::factory (const Endpoint::EndpointType type,
const std::string& specification, const std::string& specification,
int listenBacklog) { int listenBacklog,
bool reuseAddress) {
if (specification.size() < 7) { if (specification.size() < 7) {
return 0; return 0;
} }
@ -209,6 +212,11 @@ Endpoint* Endpoint::factory (const Endpoint::EndpointType type,
assert(false); assert(false);
} }
if (listenBacklog == 0 && type == ENDPOINT_SERVER) {
// use some default value
listenBacklog = 10;
}
string copy = specification; string copy = specification;
if (specification[specification.size() - 1] == '/') { if (specification[specification.size() - 1] == '/') {
// address ends with a slash => remove // address ends with a slash => remove
@ -265,14 +273,26 @@ Endpoint* Endpoint::factory (const Endpoint::EndpointType type,
// hostname and port (e.g. [address]:port) // hostname and port (e.g. [address]:port)
uint16_t port = (uint16_t) StringUtils::uint32(copy.substr(found + 2)); uint16_t port = (uint16_t) StringUtils::uint32(copy.substr(found + 2));
return new EndpointIpV6(type, encryption, specification, listenBacklog, copy.substr(1, found - 1), port); return new EndpointIpV6(type,
encryption,
specification,
listenBacklog,
reuseAddress,
copy.substr(1, found - 1),
port);
} }
found = copy.find("]", 1); found = copy.find("]", 1);
if (found != string::npos && found > 2 && found + 1 == copy.size()) { if (found != string::npos && found > 2 && found + 1 == copy.size()) {
// hostname only (e.g. [address]) // hostname only (e.g. [address])
return new EndpointIpV6(type, encryption, specification, listenBacklog, copy.substr(1, found - 1), EndpointIp::_defaultPort); return new EndpointIpV6(type,
encryption,
specification,
listenBacklog,
reuseAddress,
copy.substr(1, found - 1),
EndpointIp::_defaultPort);
} }
// invalid address specification // invalid address specification
@ -286,11 +306,23 @@ Endpoint* Endpoint::factory (const Endpoint::EndpointType type,
// hostname and port // hostname and port
uint16_t port = (uint16_t) StringUtils::uint32(copy.substr(found + 1)); uint16_t port = (uint16_t) StringUtils::uint32(copy.substr(found + 1));
return new EndpointIpV4(type, encryption, specification, listenBacklog, copy.substr(0, found), port); return new EndpointIpV4(type,
encryption,
specification,
listenBacklog,
reuseAddress,
copy.substr(0, found),
port);
} }
// hostname only // hostname only
return new EndpointIpV4(type, encryption, specification, listenBacklog, copy, EndpointIp::_defaultPort); return new EndpointIpV4(type,
encryption,
specification,
listenBacklog,
reuseAddress,
copy,
EndpointIp::_defaultPort);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -163,7 +163,9 @@ namespace triagens {
/// @brief creates a server endpoint from a string value /// @brief creates a server endpoint from a string value
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static Endpoint* serverFactory (const std::string&, int = 10); static Endpoint* serverFactory (const std::string&,
int,
bool reuseAddress);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief creates a client endpoint from a string value /// @brief creates a client endpoint from a string value
@ -177,7 +179,8 @@ namespace triagens {
static Endpoint* factory (const EndpointType type, static Endpoint* factory (const EndpointType type,
const std::string&, const std::string&,
int); int,
bool);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief compare two endpoints /// @brief compare two endpoints

View File

@ -70,9 +70,13 @@ EndpointIp::EndpointIp (const Endpoint::EndpointType type,
const Endpoint::EncryptionType encryption, const Endpoint::EncryptionType encryption,
const std::string& specification, const std::string& specification,
int listenBacklog, int listenBacklog,
bool reuseAddress,
const std::string& host, const std::string& host,
const uint16_t port) : const uint16_t port)
Endpoint(type, domainType, encryption, specification, listenBacklog), _host(host), _port(port) { : Endpoint(type, domainType, encryption, specification, listenBacklog),
_reuseAddress(reuseAddress),
_host(host),
_port(port) {
assert(domainType == DOMAIN_IPV4 || domainType == Endpoint::DOMAIN_IPV6); assert(domainType == DOMAIN_IPV4 || domainType == Endpoint::DOMAIN_IPV6);
} }
@ -122,15 +126,18 @@ TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip,
if (_type == ENDPOINT_SERVER) { if (_type == ENDPOINT_SERVER) {
// try to reuse address // try to reuse address
int opt = 1;
if (setsockopt(listenSocket.fileHandle, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*> (&opt), sizeof (opt)) == -1) {
LOG_ERROR("setsockopt() failed with %d (%s)", errno, strerror(errno));
TRI_CLOSE_SOCKET(listenSocket); if (_reuseAddress) {
int opt = 1;
if (setsockopt(listenSocket.fileHandle, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*> (&opt), sizeof (opt)) == -1) {
LOG_ERROR("setsockopt() failed with %d (%s)", errno, strerror(errno));
listenSocket.fileDescriptor = 0; TRI_CLOSE_SOCKET(listenSocket);
listenSocket.fileHandle = 0;
return listenSocket; listenSocket.fileDescriptor = 0;
listenSocket.fileHandle = 0;
return listenSocket;
}
} }
// server needs to bind to socket // server needs to bind to socket

View File

@ -54,6 +54,7 @@ namespace triagens {
const EncryptionType, const EncryptionType,
const std::string&, const std::string&,
int, int,
bool,
const std::string&, const std::string&,
const uint16_t); const uint16_t);
@ -140,6 +141,12 @@ namespace triagens {
private: private:
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not to reuse the address
////////////////////////////////////////////////////////////////////////////////
bool _reuseAddress;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief host name / address (IPv4 or IPv6) /// @brief host name / address (IPv4 or IPv6)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -48,9 +48,10 @@ EndpointIpV4::EndpointIpV4 (const Endpoint::EndpointType type,
const Endpoint::EncryptionType encryption, const Endpoint::EncryptionType encryption,
const std::string& specification, const std::string& specification,
int listenBacklog, int listenBacklog,
bool reuseAddress,
const std::string& host, const std::string& host,
const uint16_t port) : const uint16_t port)
EndpointIp(type, DOMAIN_IPV4, encryption, specification, listenBacklog, host, port) { : EndpointIp(type, DOMAIN_IPV4, encryption, specification, listenBacklog, reuseAddress, host, port) {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -54,6 +54,7 @@ namespace triagens {
const EncryptionType, const EncryptionType,
const std::string&, const std::string&,
int, int,
bool,
const std::string&, const std::string&,
const uint16_t); const uint16_t);

View File

@ -53,9 +53,10 @@ EndpointIpV6::EndpointIpV6 (const Endpoint::EndpointType type,
const Endpoint::EncryptionType encryption, const Endpoint::EncryptionType encryption,
const std::string& specification, const std::string& specification,
int listenBacklog, int listenBacklog,
bool reuseAddress,
const std::string& host, const std::string& host,
const uint16_t port) : const uint16_t port)
EndpointIp(type, DOMAIN_IPV6, encryption, specification, listenBacklog, host, port) { : EndpointIp(type, DOMAIN_IPV6, encryption, specification, listenBacklog, reuseAddress, host, port) {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -59,6 +59,7 @@ namespace triagens {
const EncryptionType, const EncryptionType,
const std::string&, const std::string&,
int, int,
bool,
const std::string&, const std::string&,
const uint16_t); const uint16_t);

View File

@ -90,6 +90,7 @@ EndpointList::~EndpointList () {
bool EndpointList::add (const std::string& specification, bool EndpointList::add (const std::string& specification,
const std::vector<std::string>& dbNames, const std::vector<std::string>& dbNames,
int backLogSize, int backLogSize,
bool reuseAddress,
Endpoint** dst) { Endpoint** dst) {
const string key = Endpoint::getUnifiedForm(specification); const string key = Endpoint::getUnifiedForm(specification);
@ -108,7 +109,7 @@ bool EndpointList::add (const std::string& specification,
return true; return true;
} }
Endpoint* ep = Endpoint::serverFactory(key, backLogSize); Endpoint* ep = Endpoint::serverFactory(key, backLogSize, reuseAddress);
if (ep == 0) { if (ep == 0) {
return false; return false;

View File

@ -96,6 +96,7 @@ namespace triagens {
bool add (const std::string&, bool add (const std::string&,
const std::vector<std::string>&, const std::vector<std::string>&,
int, int,
bool,
Endpoint** = 0); Endpoint** = 0);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -125,19 +125,6 @@ TRI_socket_t EndpointUnixDomain::connect (double connectTimeout, double requestT
return listenSocket; return listenSocket;
} }
// reuse address
int opt = 1;
if (setsockopt(listenSocket.fileHandle, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*> (&opt), sizeof (opt)) == -1) {
LOG_ERROR("setsockopt() failed with %d (%s)", errno, strerror(errno));
TRI_CLOSE_SOCKET(listenSocket);
listenSocket.fileDescriptor = 0;
listenSocket.fileHandle = 0;
return listenSocket;
}
LOG_TRACE("reuse address flag set");
struct sockaddr_un address; struct sockaddr_un address;
memset(&address, 0, sizeof(address)); memset(&address, 0, sizeof(address));

View File

@ -333,7 +333,6 @@ ApplicationScheduler::ApplicationScheduler (ApplicationServer* applicationServer
_multiSchedulerAllowed(true), _multiSchedulerAllowed(true),
_nrSchedulerThreads(4), _nrSchedulerThreads(4),
_backend(0), _backend(0),
_reuseAddress(true),
_descriptorMinimum(256) { _descriptorMinimum(256) {
} }
@ -379,14 +378,6 @@ void ApplicationScheduler::installSignalHandler (SignalTask* task) {
_scheduler->registerTask(task); _scheduler->registerTask(task);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief returns true, if address reuse is allowed
////////////////////////////////////////////////////////////////////////////////
bool ApplicationScheduler::addressReuseAllowed () {
return _reuseAddress;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- ApplicationFeature methods // --SECTION-- ApplicationFeature methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -421,18 +412,11 @@ void ApplicationScheduler::setupOptions (map<string, ProgramOptionsDescription>&
("scheduler.backend", &_backend, "1: select, 2: poll, 4: epoll") ("scheduler.backend", &_backend, "1: select, 2: poll, 4: epoll")
#endif #endif
("scheduler.report-interval", &_reportInterval, "scheduler report interval") ("scheduler.report-interval", &_reportInterval, "scheduler report interval")
("server.no-reuse-address", "do not try to reuse address")
#ifdef TRI_HAVE_GETRLIMIT #ifdef TRI_HAVE_GETRLIMIT
("server.descriptors-minimum", &_descriptorMinimum, "minimum number of file descriptors needed to start") ("server.descriptors-minimum", &_descriptorMinimum, "minimum number of file descriptors needed to start")
#endif #endif
; ;
// deprecated option, only remaining for downwards-compatibility
// reuse-address is always true
options[ApplicationServer::OPTIONS_HIDDEN]
("server.reuse-address", "try to reuse address")
;
if (_multiSchedulerAllowed) { if (_multiSchedulerAllowed) {
options["THREAD Options:help-admin"] options["THREAD Options:help-admin"]
("scheduler.threads", &_nrSchedulerThreads, "number of threads for I/O scheduler") ("scheduler.threads", &_nrSchedulerThreads, "number of threads for I/O scheduler")
@ -460,16 +444,6 @@ bool ApplicationScheduler::parsePhase1 (triagens::basics::ProgramOptions& option
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool ApplicationScheduler::parsePhase2 (triagens::basics::ProgramOptions& options) { bool ApplicationScheduler::parsePhase2 (triagens::basics::ProgramOptions& options) {
// check if want to reuse the address
if (options.has("server.reuse-address")) {
_reuseAddress = true;
}
if (options.has("server.no-reuse-address")) {
_reuseAddress = false;
}
// adjust file descriptors // adjust file descriptors
adjustFileDescriptors(); adjustFileDescriptors();

View File

@ -96,12 +96,6 @@ namespace triagens {
void installSignalHandler (SignalTask*); void installSignalHandler (SignalTask*);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns true, if address reuse is allowed
////////////////////////////////////////////////////////////////////////////////
bool addressReuseAllowed ();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- ApplicationFeature methods // --SECTION-- ApplicationFeature methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -240,12 +234,6 @@ namespace triagens {
uint32_t _backend; uint32_t _backend;
////////////////////////////////////////////////////////////////////////////////
/// @brief allow port to be reused
////////////////////////////////////////////////////////////////////////////////
bool _reuseAddress;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief minimum number of file descriptors /// @brief minimum number of file descriptors
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -2623,7 +2623,7 @@ static v8::Handle<v8::Value> JS_TestPort (v8::Arguments const& argv) {
} }
string address = TRI_ObjectToString(argv[0]); string address = TRI_ObjectToString(argv[0]);
Endpoint* endpoint = Endpoint::serverFactory(address); Endpoint* endpoint = Endpoint::serverFactory(address, 10, false);
TRI_socket_t s = endpoint->connect(1, 1); TRI_socket_t s = endpoint->connect(1, 1);
if (s.fileDescriptor == 0) { if (s.fileDescriptor == 0) {