Skip to content

Commit 546aef7

Browse files
committed
fix free service after service instance data expired
1 parent bc6607d commit 546aef7

File tree

5 files changed

+59
-46
lines changed

5 files changed

+59
-46
lines changed

polaris/plugin/local_registry/local_registry.cpp

+39-31
Original file line numberDiff line numberDiff line change
@@ -138,20 +138,38 @@ void InMemoryRegistry::RunGcTask() {
138138
service_circuit_breaker_config_data_.CheckGc(min_gc_time);
139139
}
140140

141-
Service* InMemoryRegistry::GetOrCreateServiceInLock(const ServiceKey& service_key) {
141+
Service* InMemoryRegistry::CreateServiceInLock(const ServiceKey& service_key) {
142142
Service* service = NULL;
143143
pthread_rwlock_wrlock(&rwlock_);
144144
std::map<ServiceKey, Service*>::iterator service_it = service_cache_.find(service_key);
145-
if (service_it == service_cache_.end()) {
146-
service = new Service(service_key, ++next_service_id_);
147-
service_cache_[service_key] = service;
148-
} else {
145+
POLARIS_ASSERT(service_it == service_cache_.end())
146+
service = new Service(service_key, ++next_service_id_);
147+
service_cache_[service_key] = service;
148+
pthread_rwlock_unlock(&rwlock_);
149+
return service;
150+
}
151+
152+
Service* InMemoryRegistry::GetServiceInLock(const ServiceKey& service_key) {
153+
Service* service = NULL;
154+
pthread_rwlock_wrlock(&rwlock_);
155+
std::map<ServiceKey, Service*>::iterator service_it = service_cache_.find(service_key);
156+
if (service_it != service_cache_.end()) {
149157
service = service_it->second;
150158
}
151159
pthread_rwlock_unlock(&rwlock_);
152160
return service;
153161
}
154162

163+
void InMemoryRegistry::DeleteServiceInLock(const ServiceKey& service_key) {
164+
pthread_rwlock_wrlock(&rwlock_);
165+
std::map<ServiceKey, Service*>::iterator service_it = service_cache_.find(service_key);
166+
if (service_it != service_cache_.end()) {
167+
delete service_it->second;
168+
service_cache_.erase(service_it);
169+
}
170+
pthread_rwlock_unlock(&rwlock_);
171+
}
172+
155173
void InMemoryRegistry::CheckExpireServiceData(uint64_t min_access_time,
156174
RcuMap<ServiceKey, ServiceData>& rcu_cache,
157175
ServiceDataType service_data_type) {
@@ -166,17 +184,16 @@ void InMemoryRegistry::CheckExpireServiceData(uint64_t min_access_time,
166184
if (service_data_notify_map_.erase(service_key_with_type) > 0) { // 有通知对象表示注册过handler
167185
context_->GetServerConnector()->DeregisterEventHandler(expired_services[i],
168186
service_data_type);
169-
} else { // 没有通知对象,表示未注册过handler,从磁盘加载后从未访问过的数据,直接删除数据
170-
rcu_cache.Delete(expired_services[i]);
171-
context_impl->GetServiceRecord()->ServiceDataDelete(expired_services[i], service_data_type);
172-
context_impl->GetCacheManager()->GetCachePersist().PersistServiceData(expired_services[i],
173-
service_data_type, "");
174187
}
175-
pthread_rwlock_unlock(&notify_rwlock_);
176188
if (service_data_type == kServiceDataInstances) { // 清除实例数据时对应的服务级别插件也删除
177189
context_impl->DeleteServiceContext(expired_services[i]);
178190
DeleteServiceInLock(expired_services[i]);
179191
}
192+
rcu_cache.Delete(expired_services[i]);
193+
context_impl->GetServiceRecord()->ServiceDataDelete(expired_services[i], service_data_type);
194+
context_impl->GetCacheManager()->GetCachePersist().PersistServiceData(expired_services[i],
195+
service_data_type, "");
196+
pthread_rwlock_unlock(&notify_rwlock_);
180197
}
181198
}
182199

@@ -249,6 +266,9 @@ ReturnCode InMemoryRegistry::LoadServiceDataWithNotify(const ServiceKey& service
249266
if (interval_it != service_interval_map_.end()) {
250267
refresh_interval = interval_it->second;
251268
}
269+
if (data_type == kServiceDataInstances) {
270+
CreateServiceInLock(service_key);
271+
}
252272
// 先加载磁盘缓存数据
253273
CachePersist& cache_persist = context_->GetContextImpl()->GetCacheManager()->GetCachePersist();
254274
ServiceData* disk_service_data = cache_persist.LoadServiceData(service_key, data_type);
@@ -269,25 +289,21 @@ ReturnCode InMemoryRegistry::LoadServiceDataWithNotify(const ServiceKey& service
269289
return kReturnOk;
270290
}
271291

272-
void InMemoryRegistry::DeleteServiceInLock(const ServiceKey& service_key) {
273-
pthread_rwlock_wrlock(&rwlock_);
274-
std::map<ServiceKey, Service*>::iterator service_it = service_cache_.find(service_key);
275-
if (service_it != service_cache_.end()) {
276-
delete service_it->second;
277-
service_cache_.erase(service_it);
278-
}
279-
pthread_rwlock_unlock(&rwlock_);
280-
}
281-
282292
ReturnCode InMemoryRegistry::UpdateServiceData(const ServiceKey& service_key,
283293
ServiceDataType data_type,
284294
ServiceData* service_data) {
285-
if (service_data != NULL) { // 更新服务数据指向服务
286-
Service* service = GetOrCreateServiceInLock(service_key);
295+
Service* service = GetServiceInLock(service_key);
296+
if (service != NULL) { // 更新服务数据指向服务
287297
service->UpdateData(service_data);
288298
}
289299
ContextImpl* context_impl = context_->GetContextImpl();
290300
if (data_type == kServiceDataInstances) {
301+
if (service == NULL) { // 服务被反注册了
302+
if (service_data != NULL) {
303+
service_data->DecrementRef();
304+
}
305+
return kReturnOk;
306+
}
291307
ServiceData* old_service_data = service_instances_data_.Get(service_key);
292308
if (old_service_data != NULL) {
293309
PluginManager::Instance().OnPreUpdateServiceData(old_service_data, service_data);
@@ -308,14 +324,6 @@ ReturnCode InMemoryRegistry::UpdateServiceData(const ServiceKey& service_key,
308324
POLARIS_ASSERT(false);
309325
}
310326
if (service_data == NULL) { // Server Connector反注册Handler触发更新为NULL
311-
if (data_type == kServiceDataInstances) { // 删除服务实例数据时,同时删除服务
312-
context_impl->DeleteServiceContext(service_key);
313-
DeleteServiceInLock(service_key);
314-
}
315-
context_impl->GetServiceRecord()->ServiceDataDelete(service_key,
316-
data_type); // 同步记录Service数据删除
317-
context_impl->GetCacheManager()->GetCachePersist().PersistServiceData(
318-
service_key, data_type, ""); // 异步删除磁盘服务数据
319327
return kReturnOk;
320328
}
321329
context_impl->GetServiceRecord()->ServiceDataUpdate(service_data); // 同步记录Service版本变化

polaris/plugin/local_registry/local_registry.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ class InMemoryRegistry : public LocalRegistry {
109109
ServiceDataNotify* GetOrCreateDataNotify(const ServiceKey& service_key, ServiceDataType data_type,
110110
bool& new_create);
111111

112-
Service* GetOrCreateServiceInLock(const ServiceKey& service_key);
112+
Service* CreateServiceInLock(const ServiceKey& service_key);
113+
114+
Service* GetServiceInLock(const ServiceKey& service_key);
113115

114116
void DeleteServiceInLock(const ServiceKey& service_key);
115117

test/integration/set_circuit_breaker/set_circuit_breaker_test.cpp

+12-13
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class SetCircuitBreakerTest : public IntegrationBase {
6868
ASSERT_TRUE(consumer_ != NULL);
6969

7070
SetUpServiceData();
71+
TryDoRoute();
7172
}
7273

7374
virtual void TearDown() {
@@ -358,6 +359,17 @@ class SetCircuitBreakerTest : public IntegrationBase {
358359
<< total << " " << percent << " " << err_rate << " " << count;
359360
}
360361

362+
void TryDoRoute() {
363+
polaris::GetOneInstanceRequest req(service_key_);
364+
polaris::ServiceInfo service_info;
365+
service_info.service_key_.name_ = "test2";
366+
service_info.service_key_.namespace_ = "Test";
367+
service_info.metadata_["f"] = "fv1";
368+
req.SetSourceService(service_info);
369+
polaris::Instance instance;
370+
ASSERT_EQ(consumer_->GetOneInstance(req, instance), kReturnOk);
371+
}
372+
361373
protected:
362374
polaris::ServiceKey service_key_;
363375
polaris::ConsumerApi* consumer_;
@@ -391,19 +403,6 @@ class SetCircuitBreakerTest : public IntegrationBase {
391403
std::string ins3_id_;
392404
};
393405

394-
TEST_F(SetCircuitBreakerTest, TestRoute) {
395-
ReturnCode ret;
396-
polaris::GetOneInstanceRequest req(service_key_);
397-
polaris::ServiceInfo service_info;
398-
service_info.service_key_.name_ = "test2";
399-
service_info.service_key_.namespace_ = "Test";
400-
service_info.metadata_["f"] = "fv1";
401-
req.SetSourceService(service_info);
402-
polaris::Instance instance;
403-
ret = consumer_->GetOneInstance(req, instance);
404-
ASSERT_EQ(ret, kReturnOk);
405-
}
406-
407406
TEST_F(SetCircuitBreakerTest, ErrRateOpen) {
408407
polaris::ServiceCallResult err_result;
409408
err_result.SetServiceNamespace(service_key_.namespace_);

test/plugin/load_balancer/ring_hash_test.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ TEST_F(RingHashCstLbTest, TestSelectWithInstancesUpdate) {
9797
LocalRegistry *local_registry = context_->GetLocalRegistry();
9898
local_registry->GetServiceDataWithRef(service_key_, kServiceDataInstances, service_data);
9999
ASSERT_TRUE(service_data == NULL);
100+
ServiceDataNotify *notify = NULL;
101+
local_registry->LoadServiceDataWithNotify(service_key_, kServiceDataInstances, service_data,
102+
notify);
103+
ASSERT_TRUE(notify != NULL);
100104
v1::DiscoverResponse response;
101105
CreateInstancesResponse(response);
102106

test/plugin/local_registry/local_registry_test.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ TEST_F(InMemoryLocalRegistryTest, TestUpdateServiceData) {
203203
std::set<ServiceKey> service_key_set;
204204
ret = local_registry_->GetAllServiceKey(service_key_set);
205205
ASSERT_EQ(ret, kReturnOk);
206-
ASSERT_EQ(service_key_set.size(), 1);
206+
ASSERT_EQ(service_key_set.size(), 0);
207207

208208
delete mock_server_connector_->saved_handler_;
209209
mock_server_connector_->saved_handler_ = NULL;

0 commit comments

Comments
 (0)