Skip to content

Commit 8705ba2

Browse files
Merge concurrent lookup API requests. (#858)
Used to speedup the cold start, when multiple clients concurrently tries to download the services URLs. The callers are blocked until the first caller downloads the content. Updated API lookup tests to google coding style. Relates-To: OLPEDGE-1986 Signed-off-by: Mykhailo Kuchma <ext-mykhailo.kuchma@here.com>
1 parent ee82a39 commit 8705ba2

File tree

4 files changed

+251
-48
lines changed

4 files changed

+251
-48
lines changed

olp-cpp-sdk-dataservice-read/src/ApiClientLookup.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include "generated/api/ResourcesApi.h"
3333
#include "repositories/ApiCacheRepository.h"
3434

35+
#include "repositories/NamedMutex.h"
36+
3537
namespace olp {
3638
namespace dataservice {
3739
namespace read {
@@ -58,6 +60,16 @@ ApiClientLookup::ApiClientResponse ApiClientLookup::LookupApi(
5860
client::CancellationContext cancellation_context, std::string service,
5961
std::string service_version, FetchOptions options,
6062
client::OlpClientSettings settings) {
63+
64+
// This mutex is required to avoid concurrent requests to online.
65+
repository::NamedMutex mutex(catalog.ToString());
66+
std::unique_lock<repository::NamedMutex> lock(mutex, std::adopt_lock);
67+
68+
// If we are not planning to go online or access the cache, release the lock.
69+
if (options != CacheOnly || options != OnlineOnly) {
70+
mutex.lock();
71+
}
72+
6173
repository::ApiCacheRepository repository(catalog, settings.cache);
6274
const auto hrn = catalog.ToCatalogHRNString();
6375

@@ -137,7 +149,6 @@ ApiClientLookup::ApiClientResponse ApiClientLookup::LookupApi(
137149
service_client.SetSettings(settings);
138150
return service_client;
139151
}
140-
141152
} // namespace read
142153
} // namespace dataservice
143154
} // namespace olp
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (C) 2020 HERE Europe B.V.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
* License-Filename: LICENSE
18+
*/
19+
20+
#include "NamedMutex.h"
21+
22+
#include <unordered_map>
23+
24+
namespace olp {
25+
namespace dataservice {
26+
namespace read {
27+
namespace repository {
28+
29+
namespace {
30+
31+
static std::mutex gMutex;
32+
33+
struct RefCounterMutex {
34+
std::mutex mutex;
35+
uint32_t use_count{0};
36+
};
37+
38+
static std::unordered_map<std::string, RefCounterMutex> gMutexes;
39+
40+
std::mutex& AquireLock(const std::string& resource) {
41+
std::unique_lock<std::mutex> lock(gMutex);
42+
RefCounterMutex& ref_mutex = gMutexes[resource];
43+
ref_mutex.use_count++;
44+
return ref_mutex.mutex;
45+
}
46+
47+
void ReleaseLock(const std::string& resource) {
48+
std::unique_lock<std::mutex> lock(gMutex);
49+
RefCounterMutex& ref_mutex = gMutexes[resource];
50+
if (--ref_mutex.use_count == 0) {
51+
gMutexes.erase(resource);
52+
}
53+
}
54+
55+
} // namespace
56+
57+
NamedMutex::NamedMutex(const std::string& name)
58+
: name_{name}, mutex_{AquireLock(name_)} {}
59+
60+
NamedMutex::~NamedMutex() { ReleaseLock(name_); }
61+
62+
void NamedMutex::lock() { mutex_.lock(); }
63+
64+
bool NamedMutex::try_lock() { return mutex_.try_lock(); }
65+
66+
void NamedMutex::unlock() { mutex_.unlock(); }
67+
68+
} // namespace repository
69+
} // namespace read
70+
} // namespace dataservice
71+
} // namespace olp
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (C) 2020 HERE Europe B.V.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
* License-Filename: LICENSE
18+
*/
19+
20+
#pragma once
21+
22+
#include <mutex>
23+
#include <string>
24+
25+
namespace olp {
26+
namespace dataservice {
27+
namespace read {
28+
namespace repository {
29+
30+
/*
31+
* @brief A synchronization primitive that can be used to protect shared data
32+
* from being simultaneously accessed by multiple threads.
33+
*/
34+
class NamedMutex final {
35+
public:
36+
explicit NamedMutex(const std::string& name);
37+
38+
NamedMutex(const NamedMutex&) = delete;
39+
NamedMutex(NamedMutex&&) = delete;
40+
NamedMutex& operator=(const NamedMutex&) = delete;
41+
NamedMutex& operator=(NamedMutex&&) = delete;
42+
43+
void lock();
44+
bool try_lock();
45+
void unlock();
46+
47+
~NamedMutex();
48+
49+
private:
50+
std::string name_;
51+
std::mutex& mutex_;
52+
};
53+
54+
} // namespace repository
55+
} // namespace read
56+
} // namespace dataservice
57+
} // namespace olp

0 commit comments

Comments
 (0)