summaryrefslogtreecommitdiff
path: root/cpp/src/IceGrid/AdapterCache.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2013-10-17 14:53:45 +0200
committerBenoit Foucher <benoit@zeroc.com>2013-10-17 14:53:45 +0200
commitb59a53f0e45d3137eb8d0939023417588a0c9142 (patch)
treeb5217e358bd26412e80e0fe201103af1729aeb13 /cpp/src/IceGrid/AdapterCache.cpp
parentminor edits to IceBox comments (diff)
downloadice-b59a53f0e45d3137eb8d0939023417588a0c9142.tar.bz2
ice-b59a53f0e45d3137eb8d0939023417588a0c9142.tar.xz
ice-b59a53f0e45d3137eb8d0939023417588a0c9142.zip
Fixed IceGrid registry replication bug reported by Cengage
Diffstat (limited to 'cpp/src/IceGrid/AdapterCache.cpp')
-rw-r--r--cpp/src/IceGrid/AdapterCache.cpp48
1 files changed, 38 insertions, 10 deletions
diff --git a/cpp/src/IceGrid/AdapterCache.cpp b/cpp/src/IceGrid/AdapterCache.cpp
index c267c8c55a6..9f02b0f0a0b 100644
--- a/cpp/src/IceGrid/AdapterCache.cpp
+++ b/cpp/src/IceGrid/AdapterCache.cpp
@@ -202,8 +202,12 @@ AdapterCache::addServerAdapter(const AdapterDescriptor& desc, const ServerEntryP
ReplicaGroupEntryPtr repEntry = ReplicaGroupEntryPtr::dynamicCast(getImpl(desc.replicaGroupId));
if(!repEntry)
{
- Ice::Error out(_communicator->getLogger());
- out << "can't add adapter `" << desc.id << "' to unknown replica group `" << desc.replicaGroupId << "'";
+ //
+ // Add an un-assigned replica group, the replica group will in theory be added
+ // shortly after when its application is loaded.
+ //
+ repEntry = new ReplicaGroupEntry(*this, desc.replicaGroupId, "", new RandomLoadBalancingPolicy("0"));
+ addImpl(desc.replicaGroupId, repEntry);
}
repEntry->addReplica(desc.id, entry);
}
@@ -213,13 +217,24 @@ void
AdapterCache::addReplicaGroup(const ReplicaGroupDescriptor& desc, const string& app)
{
Lock sync(*this);
- if(getImpl(desc.id))
+ ReplicaGroupEntryPtr repEntry = ReplicaGroupEntryPtr::dynamicCast(getImpl(desc.id));
+ if(repEntry)
{
- Ice::Error out(_communicator->getLogger());
- out << "can't add duplicate replica group `" << desc.id << "'";
+ //
+ // If the replica group isn't assigned to an application,
+ // assign it. Otherwise, it's a duplicate so we log an error.
+ //
+ if(repEntry->getApplication().empty())
+ {
+ repEntry->update(app, desc.loadBalancing);
+ }
+ else
+ {
+ Ice::Error out(_communicator->getLogger());
+ out << "can't add duplicate replica group `" << desc.id << "'";
+ }
return;
}
-
addImpl(desc.id, new ReplicaGroupEntry(*this, desc.id, app, desc.loadBalancing));
}
@@ -258,7 +273,16 @@ AdapterCache::removeServerAdapter(const string& id)
Ice::Error out(_communicator->getLogger());
out << "can't remove adapter `" << id << "' from unknown replica group `" << replicaGroupId << "'";
}
- repEntry->removeReplica(id);
+ else
+ {
+ //
+ // If the replica group is empty and it's not assigned, remove it.
+ //
+ if(repEntry->removeReplica(id))
+ {
+ removeImpl(replicaGroupId);
+ }
+ }
}
}
@@ -440,7 +464,7 @@ ReplicaGroupEntry::ReplicaGroupEntry(AdapterCache& cache,
_lastReplica(0),
_requestInProgress(false)
{
- update(policy);
+ update(application, policy);
}
bool
@@ -502,7 +526,7 @@ ReplicaGroupEntry::addReplica(const string& /*replicaId*/, const ServerAdapterEn
_replicas.push_back(adapter);
}
-void
+bool
ReplicaGroupEntry::removeReplica(const string& replicaId)
{
Lock sync(*this);
@@ -516,14 +540,18 @@ ReplicaGroupEntry::removeReplica(const string& replicaId)
break;
}
}
+
+ // Replica group can be removed if not assigned to an application and there's no more replicas
+ return _replicas.empty() && _application.empty();
}
void
-ReplicaGroupEntry::update(const LoadBalancingPolicyPtr& policy)
+ReplicaGroupEntry::update(const string& application, const LoadBalancingPolicyPtr& policy)
{
Lock sync(*this);
assert(policy);
+ _application = application;
_loadBalancing = policy;
istringstream is(_loadBalancing->nReplicas);