summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDwight <dmerriman@gmail.com>2008-09-11 09:15:34 -0400
committerDwight <dmerriman@gmail.com>2008-09-11 09:15:34 -0400
commit5f163f72b8a9bf3924092af1bb695c7606ae7eb8 (patch)
tree41b15f6626ac6718a54494775a84418609a4d6d7
parentf2bee299e426865e92b03c49dc16ff997bd88fd0 (diff)
downloadmongo-5f163f72b8a9bf3924092af1bb695c7606ae7eb8.tar.gz
dbgrid.vcproj missing; more work on dbgridr0.1.2_rc1
-rw-r--r--db/jsobj.cpp7
-rw-r--r--db/jsobj.h2
-rw-r--r--db/repl.cpp109
-rw-r--r--db/repl.h2
-rw-r--r--db/replset.h17
-rw-r--r--dbgrid/dbgrid.vcproj256
-rw-r--r--util/goodies.h6
7 files changed, 397 insertions, 2 deletions
diff --git a/db/jsobj.cpp b/db/jsobj.cpp
index 8687321f3e4..dc981941167 100644
--- a/db/jsobj.cpp
+++ b/db/jsobj.cpp
@@ -19,6 +19,8 @@
#include "stdafx.h"
#include "jsobj.h"
#include "../util/goodies.h"
+#include <limits>
+
Element nullElement;
@@ -367,6 +369,11 @@ JSObj JSObj::extractFields(JSObj& pattern) {
return b.doneAndDecouple();
}
+int JSObj::getIntField(const char *name) {
+ Element e = getField(name);
+ return e.type() == Number ? (int) e.number() : INT_MIN;
+}
+
bool JSObj::getBoolField(const char *name) {
Element e = getField(name);
return e.type() == Bool ? e.boolean() : false;
diff --git a/db/jsobj.h b/db/jsobj.h
index 810442def45..4b630b0de27 100644
--- a/db/jsobj.h
+++ b/db/jsobj.h
@@ -241,6 +241,8 @@ public:
JSObj getObjectField(const char *name);
+ int getIntField(const char *name); // INT_MIN if not present
+
bool getBoolField(const char *name);
/* makes a new JSObj with the fields specified in pattern.
diff --git a/db/repl.cpp b/db/repl.cpp
index e41473b0e5c..2c301f4735d 100644
--- a/db/repl.cpp
+++ b/db/repl.cpp
@@ -33,6 +33,7 @@
#include "query.h"
#include "json.h"
#include "db.h"
+#include "commands.h"
extern int port;
extern boost::mutex dbMutex;
@@ -47,6 +48,103 @@ void ensureHaveIdIndex(const char *ns);
ReplPair *replPair = 0;
+class CmdIsMaster : public Command {
+public:
+ CmdIsMaster() : Command("ismaster") { }
+
+ virtual bool run(const char *ns, JSObj& cmdObj, string& errmsg, JSObjBuilder& result) {
+ int x = -2;
+ if( replPair ) {
+ x = replPair->state;
+ }
+ else {
+ result.append("msg", "not paired");
+ }
+ result.append("ismaster", x);
+ return true;
+ }
+} cmdismaster;
+
+/* negotiate who is master
+
+ -1=not set (probably means we just booted)
+ 0=was slave
+ 1=was master
+
+ remote,local -> new remote,local
+ !1,1 -> 0,1
+ 1,!1 -> 1,0
+ -1,-1 -> dominant->1, nondom->0
+ 0,0 -> dominant->1, nondom->0
+ 1,1 -> dominant->1, nondom->0
+
+ { negotiatemaster:1, i_was:<state>, your_name:<hostname> }
+ returns:
+ { ok:1, you_are:..., i_am:... }
+*/
+class CmdNegotiateMaster : public Command {
+public:
+ CmdNegotiateMaster() : Command("negotiatemaster") { }
+
+ virtual bool adminOnly() { return true; }
+
+ virtual bool run(const char *ns, JSObj& cmdObj, string& errmsg, JSObjBuilder& result) {
+ if( replPair == 0 ) {
+ problem() << "got negotiatemaster cmd but we are not in paired mode." << endl;
+ errmsg = "not paired";
+ return false;
+ }
+
+ int was = cmdObj.getIntField("i_was");
+ string myname = cmdObj.getStringField("your_name");
+ if( myname.empty() || was < -1 ) {
+ errmsg = "your_name/i_was not specified";
+ return false;
+ }
+
+ int me, you;
+ if( was == replPair->state ) {
+ if( replPair->dominant(myname) ) {
+ me=1;you=0;
+ }
+ else {
+ me=0;you=1;
+ }
+ }
+ else if( was == 1 ) {
+ me=0;you=1;
+ }
+ else {
+ me=1;you=0;
+ }
+
+ replPair->state = me;
+ result.append("you_are", you);
+ result.append("i_am", me);
+
+ return true;
+ }
+} cmdnegotiatemaster;
+
+void ReplPair::negotiate(DBClientConnection *conn) {
+ JSObjBuilder b;
+ b.append("negotiatemaster",1);
+ b.append("i_was", state);
+ b.append("your_name", remoteHost);
+ JSObj cmd = b.done();
+ JSObj res = conn->findOne("admin.$cmd", cmd);
+ if( res.getIntField("ok") != 1 ) {
+ problem() << "negotiate fails: " << res.toString() << '\n';
+ return;
+ }
+ int x = res.getIntField("you_are");
+ if( x != 0 && x != 1 ) {
+ problem() << "negotiate: bad you_are value " << res.toString() << endl;
+ return;
+ }
+ setMaster(x);
+}
+
OpTime last(0, 0);
OpTime OpTime::now() {
@@ -177,8 +275,10 @@ void ReplSource::loadAll(vector<ReplSource*>& v) {
auto_ptr<Cursor> c = findTableScan("local.sources", emptyObj);
while( c->ok() ) {
ReplSource tmp(c->current());
- if( replPair && tmp.hostName == replPair->remote && tmp.sourceName == "main" )
+ if( replPair && tmp.hostName == replPair->remote && tmp.sourceName == "main" ) {
gotPairWith = true;
+ tmp.paired = true;
+ }
addSourceToList(v, tmp, old);
c->advance();
}
@@ -450,6 +550,10 @@ bool ReplSource::sync() {
conn = auto_ptr<DBClientConnection>(new DBClientConnection());
string errmsg;
if( !conn->connect(hostName.c_str(), errmsg) ) {
+ if( replPair && paired ) {
+ assert( startsWith(hostName.c_str(), replPair->remoteHost.c_str()) );
+ replPair->setMaster(1);
+ }
resetConnection();
log() << "pull: cantconn " << errmsg << endl;
sleepsecs(1);
@@ -457,6 +561,9 @@ bool ReplSource::sync() {
}
}
+ if( paired )
+ replPair->negotiate(conn.get());
+
/*
// get current mtime at the server.
JSObj o = conn->findOne("admin.$cmd", opTimeQuery);
diff --git a/db/repl.h b/db/repl.h
index 52f2719073f..43c52c3232d 100644
--- a/db/repl.h
+++ b/db/repl.h
@@ -98,7 +98,7 @@ class ReplSource {
ReplSource();
public:
bool paired; // --pair in use
- string hostName; // ip addr or hostname
+ string hostName; // ip addr or hostname plus optionally, ":<port>"
string sourceName; // a logical source name.
string only; // only a certain db. note that in the sources collection, this may not be changed once you start replicating.
diff --git a/db/replset.h b/db/replset.h
index 58b32046b55..9d3eb8dbe03 100644
--- a/db/replset.h
+++ b/db/replset.h
@@ -30,15 +30,32 @@
class ReplPair {
public:
+ int state;
int remotePort;
string remoteHost;
string remote; // host:port if port specified.
+ int date; // -1 not yet set; 0=slave; 1=master
ReplPair(const char *remoteEnd);
+ bool dominant(const string& myname) {
+ if( myname == remoteHost )
+ return port > remotePort;
+ return myname > remoteHost;
+ }
+
+ void setMaster(int n) {
+ if( n == state )
+ return;
+ log() << "pair: setting master=" << n << " was " << state << '\n';
+ state = n;
+ }
+
+ void negotiate(DBClientConnection *conn);
};
ReplPair::ReplPair(const char *remoteEnd) {
+ state = -1;
remote = remoteEnd;
remotePort = DBPort;
remoteHost = remoteEnd;
diff --git a/dbgrid/dbgrid.vcproj b/dbgrid/dbgrid.vcproj
new file mode 100644
index 00000000000..9355686e9c9
--- /dev/null
+++ b/dbgrid/dbgrid.vcproj
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="dbgrid"
+ ProjectGUID="{E03717ED-69B4-4D21-BC55-DF6690B585C6}"
+ RootNamespace="dbgrid"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;..\pcre-7.4&quot;;..\boost"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_SCL_SECURE_NO_DEPRECATE;BOOST_ALL_NO_LIB;BOOST_LIB_DIAGNOSTIC;_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\dbgrid.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\util\goodies.h"
+ >
+ </File>
+ <File
+ RelativePath="..\stdafx.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <Filter
+ Name="libs_etc"
+ >
+ <File
+ RelativePath="..\..\boostw\boost_1_34_1\boost\config\auto_link.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\boost\boost\Debug\boost.lib"
+ >
+ </File>
+ <File
+ RelativePath="..\..\boostw\boost_1_34_1\boost\version.hpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Shared Source Files"
+ >
+ <File
+ RelativePath="..\db\dbclient.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\db\jsobj.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\grid\message.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\util\sock.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\util\util.cpp"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/util/goodies.h b/util/goodies.h
index a400a39b280..c08ee8fc0d6 100644
--- a/util/goodies.h
+++ b/util/goodies.h
@@ -192,6 +192,12 @@ public:
//typedef boostlock lock;
+inline bool startsWith(const char *str, const char *prefix) {
+ unsigned l = strlen(prefix);
+ if( strlen(str) < l ) return false;
+ return strncmp(str, prefix, l) == 0;
+}
+
inline bool endsWith(const char *p, const char *suffix) {
int a = strlen(p);
int b = strlen(suffix);