local sync: disambiguate source names
During local sync names like "addressbook" are no longer unique, because they may exist in both the local and the remote context. This patch introduces a "display name" composed from context and source name, like this: "@<context>/<source>" (@default/addressbook). The context is only used if needed, which currently is the case during a local sync. Changing the SyncSourceBase::getName() result was also considered, but several places expect this to be the name of the source inside its context, so an explicit SyncSourceBase::getDisplayName() turned out to be safer.
This commit is contained in:
parent
783cad557e
commit
a9ee4e87ee
4 changed files with 77 additions and 41 deletions
|
@ -132,7 +132,7 @@ void LocalTransportAgent::run()
|
|||
// process.
|
||||
int res = 0;
|
||||
try {
|
||||
SE_LOG_INFO(NULL, NULL, "client is running");
|
||||
SE_LOG_DEBUG(NULL, NULL, "client is running");
|
||||
// TODO: password and abort handling in a derived class
|
||||
SyncContext client(std::string("source-config") + m_clientContext,
|
||||
m_server->getRootPath() + "/." + m_clientContext,
|
||||
|
|
|
@ -1539,20 +1539,20 @@ void SyncContext::displaySourceProgress(sysync::TProgressEventEnum type,
|
|||
// not active, suppress output
|
||||
} else if (extra2) {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: preparing %d/%d",
|
||||
source.getName(), extra1, extra2);
|
||||
source.getDisplayName(), extra1, extra2);
|
||||
} else {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: preparing %d",
|
||||
source.getName(), extra1);
|
||||
source.getDisplayName(), extra1);
|
||||
}
|
||||
break;
|
||||
case sysync::PEV_DELETING:
|
||||
/* deleting (zapping datastore), extra1=progress, extra2=total */
|
||||
if (extra2) {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: deleting %d/%d",
|
||||
source.getName(), extra1, extra2);
|
||||
source.getDisplayName(), extra1, extra2);
|
||||
} else {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: deleting %d",
|
||||
source.getName(), extra1);
|
||||
source.getDisplayName(), extra1);
|
||||
}
|
||||
break;
|
||||
case sysync::PEV_ALERTED: {
|
||||
|
@ -1562,7 +1562,7 @@ void SyncContext::displaySourceProgress(sysync::TProgressEventEnum type,
|
|||
// -1 is used for alerting a restore from backup. Synthesis won't use this
|
||||
if (extra1 != -1) {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: %s %s sync%s",
|
||||
source.getName(),
|
||||
source.getDisplayName(),
|
||||
extra2 ? "resuming" : "starting",
|
||||
extra1 == 0 ? "normal" :
|
||||
extra1 == 1 ? "slow" :
|
||||
|
@ -1607,7 +1607,7 @@ void SyncContext::displaySourceProgress(sysync::TProgressEventEnum type,
|
|||
source.recordFirstSync(extra1 == 2);
|
||||
source.recordResumeSync(extra2 == 1);
|
||||
} else {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: restore from backup", source.getName());
|
||||
SE_LOG_INFO(NULL, NULL, "%s: restore from backup", source.getDisplayName());
|
||||
source.recordFinalSyncMode(SYNC_RESTORE_FROM_BACKUP);
|
||||
}
|
||||
break;
|
||||
|
@ -1615,7 +1615,7 @@ void SyncContext::displaySourceProgress(sysync::TProgressEventEnum type,
|
|||
case sysync::PEV_SYNCSTART:
|
||||
/* sync started */
|
||||
SE_LOG_INFO(NULL, NULL, "%s: started",
|
||||
source.getName());
|
||||
source.getDisplayName());
|
||||
break;
|
||||
case sysync::PEV_ITEMRECEIVED:
|
||||
/* item received, extra1=current item count,
|
||||
|
@ -1623,10 +1623,10 @@ void SyncContext::displaySourceProgress(sysync::TProgressEventEnum type,
|
|||
if (source.getFinalSyncMode() == SYNC_NONE) {
|
||||
} else if (extra2 > 0) {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: received %d/%d",
|
||||
source.getName(), extra1, extra2);
|
||||
source.getDisplayName(), extra1, extra2);
|
||||
} else {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: received %d",
|
||||
source.getName(), extra1);
|
||||
source.getDisplayName(), extra1);
|
||||
}
|
||||
break;
|
||||
case sysync::PEV_ITEMSENT:
|
||||
|
@ -1635,10 +1635,10 @@ void SyncContext::displaySourceProgress(sysync::TProgressEventEnum type,
|
|||
if (source.getFinalSyncMode() == SYNC_NONE) {
|
||||
} else if (extra2 > 0) {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: sent %d/%d",
|
||||
source.getName(), extra1, extra2);
|
||||
source.getDisplayName(), extra1, extra2);
|
||||
} else {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: sent %d",
|
||||
source.getName(), extra1);
|
||||
source.getDisplayName(), extra1);
|
||||
}
|
||||
break;
|
||||
case sysync::PEV_ITEMPROCESSED:
|
||||
|
@ -1648,7 +1648,7 @@ void SyncContext::displaySourceProgress(sysync::TProgressEventEnum type,
|
|||
if (source.getFinalSyncMode() == SYNC_NONE) {
|
||||
} else if (source.getFinalSyncMode() != SYNC_NONE) {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: added %d, updated %d, removed %d",
|
||||
source.getName(), extra1, extra2, extra3);
|
||||
source.getDisplayName(), extra1, extra2, extra3);
|
||||
}
|
||||
break;
|
||||
case sysync::PEV_SYNCEND:
|
||||
|
@ -1656,14 +1656,14 @@ void SyncContext::displaySourceProgress(sysync::TProgressEventEnum type,
|
|||
syncmode in extra2 (0=normal, 1=slow, 2=first time),
|
||||
extra3=1 for resumed session) */
|
||||
if (source.getFinalSyncMode() == SYNC_NONE) {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: inactive", source.getName());
|
||||
SE_LOG_INFO(NULL, NULL, "%s: inactive", source.getDisplayName());
|
||||
} else if(source.getFinalSyncMode() == SYNC_RESTORE_FROM_BACKUP) {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: restore done %s",
|
||||
source.getName(),
|
||||
source.getDisplayName(),
|
||||
extra1 ? "unsuccessfully" : "successfully" );
|
||||
} else {
|
||||
SE_LOG_INFO(NULL, NULL, "%s: %s%s sync done %s",
|
||||
source.getName(),
|
||||
source.getDisplayName(),
|
||||
extra3 ? "resumed " : "",
|
||||
extra2 == 0 ? "normal" :
|
||||
extra2 == 1 ? "slow" :
|
||||
|
@ -1792,7 +1792,7 @@ void SyncContext::displaySourceProgress(sysync::TProgressEventEnum type,
|
|||
break;
|
||||
default:
|
||||
SE_LOG_DEBUG(NULL, NULL, "%s: progress event %d, extra %d/%d/%d",
|
||||
source.getName(),
|
||||
source.getDisplayName(),
|
||||
type, extra1, extra2, extra3);
|
||||
}
|
||||
}
|
||||
|
@ -1896,6 +1896,15 @@ void SyncContext::initSources(SourceList &sourceList)
|
|||
list<string> configuredSources = getSyncSources();
|
||||
map<string, string> subSources;
|
||||
|
||||
// Disambiguate source names because we have multiple with the same
|
||||
// name active?
|
||||
string contextName;
|
||||
if (m_localSync) {
|
||||
string dummy;
|
||||
splitConfigString(getConfigName(), dummy, contextName);
|
||||
contextName.insert(0, "@");
|
||||
}
|
||||
|
||||
// Phase 1, check all virtual sync soruces
|
||||
BOOST_FOREACH(const string &name, configuredSources) {
|
||||
boost::shared_ptr<PersistentSyncSourceConfig> sc(getSyncSourceConfig(name));
|
||||
|
@ -1908,7 +1917,7 @@ void SyncContext::initSources(SourceList &sourceList)
|
|||
if (sourceType.m_backend == "virtual") {
|
||||
//This is a virtual sync source, check and enable the referenced
|
||||
//sub syncsources here
|
||||
SyncSourceParams params(name, source, boost::shared_ptr<SyncConfig>(this, SyncConfigNOP()));
|
||||
SyncSourceParams params(name, source, boost::shared_ptr<SyncConfig>(this, SyncConfigNOP()), contextName);
|
||||
boost::shared_ptr<VirtualSyncSource> vSource = boost::shared_ptr<VirtualSyncSource> (new VirtualSyncSource (params));
|
||||
std::vector<std::string> mappedSources = vSource->getMappedSources();
|
||||
BOOST_FOREACH (std::string source, mappedSources) {
|
||||
|
@ -1954,7 +1963,8 @@ void SyncContext::initSources(SourceList &sourceList)
|
|||
if (sourceType.m_backend != "virtual") {
|
||||
SyncSourceParams params(name,
|
||||
source,
|
||||
boost::shared_ptr<SyncConfig>(this, SyncConfigNOP()));
|
||||
boost::shared_ptr<SyncConfig>(this, SyncConfigNOP()),
|
||||
contextName);
|
||||
cxxptr<SyncSource> syncSource(SyncSource::createSource(params));
|
||||
if (!syncSource) {
|
||||
throwError(name + ": type unknown" );
|
||||
|
@ -1968,7 +1978,7 @@ void SyncContext::initSources(SourceList &sourceList)
|
|||
// the Synthesis engine is never going to see this source,
|
||||
// therefore we have to mark it as 100% complete and
|
||||
// "done"
|
||||
class DummySyncSource source(name);
|
||||
class DummySyncSource source(name, contextName);
|
||||
source.recordFinalSyncMode(SYNC_NONE);
|
||||
displaySourceProgress(sysync::PEV_PREPARING,
|
||||
source,
|
||||
|
@ -2444,7 +2454,7 @@ void SyncContext::getConfigXML(string &xml, string &configname)
|
|||
sourceType.m_forceFormat != subType.m_forceFormat)) {
|
||||
SE_LOG_WARNING(NULL, NULL,
|
||||
"Virtual data source \"%s\" and sub data source \"%s\" have different data format. Will use the format in virtual data source.",
|
||||
vSource->getName(), source.c_str());
|
||||
vSource->getDisplayName(), source.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2698,6 +2708,9 @@ SyncMLStatus SyncContext::sync(SyncReport *report)
|
|||
SwapContext syncSentinel(this);
|
||||
try {
|
||||
m_sourceListPtr = &sourceList;
|
||||
if (boost::starts_with(getUsedSyncURL(), "local://")) {
|
||||
m_localSync = true;
|
||||
}
|
||||
|
||||
if (getenv("SYNCEVOLUTION_GNUTLS_DEBUG")) {
|
||||
// Enable libgnutls debugging without creating a hard dependency on it,
|
||||
|
@ -2731,10 +2744,6 @@ SyncMLStatus SyncContext::sync(SyncReport *report)
|
|||
getLogLevel(),
|
||||
report);
|
||||
|
||||
if (boost::starts_with(getUsedSyncURL(), "local://")) {
|
||||
m_localSync = true;
|
||||
}
|
||||
|
||||
/* Must detect server or client session before creating the
|
||||
* underlying SynthesisEngine
|
||||
* */
|
||||
|
|
|
@ -54,7 +54,7 @@ void SyncSourceBase::throwError(const string &action, int error)
|
|||
|
||||
void SyncSourceBase::throwError(const string &failure)
|
||||
{
|
||||
SyncContext::throwError(string(getName()) + ": " + failure);
|
||||
SyncContext::throwError(string(getDisplayName()) + ": " + failure);
|
||||
}
|
||||
|
||||
SyncMLStatus SyncSourceBase::handleException()
|
||||
|
@ -73,7 +73,7 @@ void SyncSourceBase::messagev(Level level,
|
|||
const char *format,
|
||||
va_list args)
|
||||
{
|
||||
string newprefix = getName();
|
||||
string newprefix = getDisplayName();
|
||||
if (prefix) {
|
||||
newprefix += ": ";
|
||||
newprefix += prefix;
|
||||
|
@ -177,6 +177,14 @@ string SyncSourceBase::getNativeDatatypeName()
|
|||
return info.m_native;
|
||||
}
|
||||
|
||||
SyncSource::SyncSource(const SyncSourceParams ¶ms) :
|
||||
SyncSourceConfig(params.m_name, params.m_nodes),
|
||||
m_numDeleted(0),
|
||||
m_forceSlowSync(false),
|
||||
m_name(params.getDisplayName())
|
||||
{
|
||||
}
|
||||
|
||||
SDKInterface *SyncSource::getSynthesisAPI() const
|
||||
{
|
||||
return m_synthesisAPI.empty() ?
|
||||
|
@ -317,7 +325,7 @@ SyncSource *SyncSource::createSource(const SyncSourceParams ¶ms, bool error,
|
|||
SyncSource *source = NULL;
|
||||
source = new VirtualSyncSource(params, config);
|
||||
if (error && !source) {
|
||||
SyncContext::throwError(params.m_name + ": virtual source cannot be instantiated");
|
||||
SyncContext::throwError(params.getDisplayName() + ": virtual source cannot be instantiated");
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
@ -327,8 +335,8 @@ SyncSource *SyncSource::createSource(const SyncSourceParams ¶ms, bool error,
|
|||
SyncSource *source = sourceInfos->m_create(params);
|
||||
if (source) {
|
||||
if (source == RegisterSyncSource::InactiveSource) {
|
||||
SyncContext::throwError(params.m_name + ": access to " + sourceInfos->m_shortDescr +
|
||||
" not enabled, therefore type = " + sourceTypeString + " not supported");
|
||||
SyncContext::throwError(params.getDisplayName() + ": access to " + sourceInfos->m_shortDescr +
|
||||
" not enabled, therefore type = " + sourceTypeString + " not supported");
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
|
|
@ -53,18 +53,26 @@ struct SyncSourceParams {
|
|||
* Testing uses "source-config@client-test". On the
|
||||
* command line, this is the config chosen by the
|
||||
* user, which may or may not have peer-specific settings!
|
||||
* @param contextName optional name of context in which the source is defined,
|
||||
* needed to disambiguates "name" when sources from
|
||||
* different contexts are active in a sync
|
||||
*/
|
||||
SyncSourceParams(const string &name,
|
||||
const SyncSourceNodes &nodes,
|
||||
const boost::shared_ptr<const SyncConfig> &context) :
|
||||
const boost::shared_ptr<const SyncConfig> &context,
|
||||
const string &contextName = "") :
|
||||
m_name(name),
|
||||
m_nodes(nodes),
|
||||
m_context(context)
|
||||
m_context(context),
|
||||
m_contextName(contextName)
|
||||
{}
|
||||
|
||||
std::string getDisplayName() const { return m_contextName.empty() ? m_name : m_contextName + "/" + m_name; }
|
||||
|
||||
string m_name;
|
||||
SyncSourceNodes m_nodes;
|
||||
boost::shared_ptr<const SyncConfig> m_context;
|
||||
string m_contextName;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -555,9 +563,21 @@ class SyncSourceBase : public Logger {
|
|||
public:
|
||||
virtual ~SyncSourceBase() {}
|
||||
|
||||
/** the unique name of the sync source (for example, "addressbook") */
|
||||
/**
|
||||
* the name of the sync source (for example, "addressbook"),
|
||||
* unique in the context of its own configuration
|
||||
**/
|
||||
virtual const char *getName() const { return "uninitialized SyncSourceBase"; }
|
||||
|
||||
/**
|
||||
* the name of the sync source as it should be displayed to users
|
||||
* in debug messages; typically the same as getName(), but may
|
||||
* also include a context ("@foobar/addressbook") to disambiguate
|
||||
* the name when "addressbook" is used multiple times in a sync (as
|
||||
* with local sync)
|
||||
*/
|
||||
virtual const char *getDisplayName() const { return "uninitialized SyncSourceBase"; }
|
||||
|
||||
/**
|
||||
* Convenience function, to be called inside a catch() block of
|
||||
* (or for) the sync source.
|
||||
|
@ -751,12 +771,7 @@ class SyncSourceBase : public Logger {
|
|||
class SyncSource : virtual public SyncSourceBase, public SyncSourceConfig, public SyncSourceReport
|
||||
{
|
||||
public:
|
||||
SyncSource(const SyncSourceParams ¶ms) :
|
||||
SyncSourceConfig(params.m_name, params.m_nodes),
|
||||
m_numDeleted(0),
|
||||
m_forceSlowSync(false)
|
||||
{
|
||||
}
|
||||
SyncSource(const SyncSourceParams ¶ms);
|
||||
virtual ~SyncSource() {}
|
||||
|
||||
/**
|
||||
|
@ -1109,6 +1124,7 @@ class SyncSource : virtual public SyncSourceBase, public SyncSourceConfig, publi
|
|||
|
||||
/* implementation of SyncSourceBase */
|
||||
virtual const char * getName() const { return SyncSourceConfig::getName(); }
|
||||
virtual const char * getDisplayName() const { return m_name.c_str(); }
|
||||
virtual long getNumDeleted() const { return m_numDeleted; }
|
||||
virtual void setNumDeleted(long num) { m_numDeleted = num; }
|
||||
virtual void incrementNumDeleted() { m_numDeleted++; }
|
||||
|
@ -1146,6 +1162,9 @@ class SyncSource : virtual public SyncSourceBase, public SyncSourceConfig, publi
|
|||
* the engine is running.
|
||||
*/
|
||||
std::vector<sysync::SDK_InterfaceType *> m_synthesisAPI;
|
||||
|
||||
/** actual name of the source */
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1157,8 +1176,8 @@ class DummySyncSource : public SyncSource
|
|||
DummySyncSource(const SyncSourceParams ¶ms) :
|
||||
SyncSource(params) {}
|
||||
|
||||
DummySyncSource(const std::string &name) :
|
||||
SyncSource(SyncSourceParams(name, SyncSourceNodes(), boost::shared_ptr<const SyncConfig>())) {}
|
||||
DummySyncSource(const std::string &name, const std::string &contextName) :
|
||||
SyncSource(SyncSourceParams(name, SyncSourceNodes(), boost::shared_ptr<const SyncConfig>(), contextName)) {}
|
||||
|
||||
virtual Databases getDatabases() { return Databases(); }
|
||||
virtual void open() {}
|
||||
|
|
Loading…
Reference in a new issue