6
6
#include " util/util.hpp"
7
7
#include " util/win32_undef.hpp"
8
8
#include " preferences/preferences.hpp"
9
+ #include " util/str_util.hpp"
9
10
#include < list>
10
11
#include < iomanip>
12
+ #include < atomic>
11
13
12
14
namespace horizon {
13
15
@@ -71,6 +73,18 @@ std::string StockInfoProviderDigiKey::update_tokens_from_response(SQLite::Databa
71
73
return access_token;
72
74
}
73
75
76
+ static int remaining_from_headers (const HTTP::Client::ResponseHeaders &headers)
77
+ {
78
+ for (const auto &it : headers) {
79
+ if (it.find (" X-RateLimit-Remaining:" ) == 0 ) {
80
+ std::string s = it.substr (22 );
81
+ trim (s);
82
+ return std::stoi (s);
83
+ }
84
+ }
85
+ return 0 ;
86
+ }
87
+
74
88
class DigiKeyCacheManager {
75
89
public:
76
90
static std::shared_ptr<DigiKeyCacheManager> &get ()
@@ -103,9 +117,10 @@ class DigiKeyCacheManager {
103
117
}
104
118
}
105
119
106
- json query (const std::string &MPN, const std::string &manufacturer)
120
+ std::pair< json, unsigned int > query (const std::string &MPN, const std::string &manufacturer)
107
121
{
108
122
std::unique_lock<std::mutex> lk (mutex);
123
+ unsigned int n_remaining = 0 ;
109
124
110
125
json j;
111
126
std::string access_token;
@@ -133,6 +148,11 @@ class DigiKeyCacheManager {
133
148
}
134
149
cache_db.execute (" COMMIT" );
135
150
}
151
+ catch (const std::exception &e) {
152
+ std::cerr << e.what () << std::endl;
153
+ cache_db.execute (" ROLLBACK" );
154
+ return {};
155
+ }
136
156
catch (...) {
137
157
cache_db.execute (" ROLLBACK" );
138
158
return {};
@@ -163,6 +183,8 @@ class DigiKeyCacheManager {
163
183
{" ExcludeMarketPlaceProducts" , true },
164
184
};
165
185
const json response = rest_client.post (" Search/v3/Products/Keyword" , query);
186
+ n_remaining = remaining_from_headers (rest_client.get_response_headers ());
187
+
166
188
{
167
189
SQLite::Query q_insert (
168
190
cache_db,
@@ -173,7 +195,7 @@ class DigiKeyCacheManager {
173
195
q_insert.bind (3 , response.dump ());
174
196
q_insert.step ();
175
197
}
176
- return response;
198
+ return { response, n_remaining} ;
177
199
}
178
200
catch (const std::exception &e) {
179
201
std::cout << e.what () << std::endl;
@@ -284,6 +306,11 @@ class StockInfoProviderDigiKeyWorker {
284
306
return n_items_fetched;
285
307
}
286
308
309
+ unsigned int get_n_remaining () const
310
+ {
311
+ return n_remaining;
312
+ }
313
+
287
314
private:
288
315
Pool pool;
289
316
std::shared_ptr<class DigiKeyCacheManager > cache_mgr;
@@ -316,9 +343,10 @@ class StockInfoProviderDigiKeyWorker {
316
343
void emit ();
317
344
std::thread fetch_thread;
318
345
319
- unsigned int n_items_from_cache = 0 ;
320
- unsigned int n_items_to_fetch = 0 ;
321
- unsigned int n_items_fetched = 0 ;
346
+ std::atomic<unsigned int > n_items_from_cache = 0 ;
347
+ std::atomic<unsigned int > n_items_to_fetch = 0 ;
348
+ std::atomic<unsigned int > n_items_fetched = 0 ;
349
+ std::atomic<unsigned int > n_remaining = 0 ;
322
350
};
323
351
324
352
void StockInfoProviderDigiKeyWorker::emit ()
@@ -409,8 +437,9 @@ void StockInfoProviderDigiKeyWorker::fetch_worker()
409
437
for (const auto &[uu, MPN, manufacturer] : my_parts) {
410
438
n_items_fetched++;
411
439
412
- const auto r = cache_mgr->query (MPN, manufacturer);
440
+ const auto [r, remaining] = cache_mgr->query (MPN, manufacturer);
413
441
add_record (uu, r, MPN, manufacturer);
442
+ n_remaining = remaining;
414
443
415
444
if (my_parts_rev != parts_rev_fetch) {
416
445
cancel = true ;
@@ -546,6 +575,9 @@ StockInfoProviderDigiKey::StockInfoProviderDigiKey(const std::string &pool_base_
546
575
if (worker->get_n_items_to_fetch ()) {
547
576
txt += " , fetching " + format_m_of_n (worker->get_n_items_fetched (), worker->get_n_items_to_fetch ());
548
577
}
578
+ if (auto remaining = worker->get_n_remaining ()) {
579
+ txt += " , " + std::to_string (remaining) + " queries remaining" ;
580
+ }
549
581
status_label->set_text (txt);
550
582
}
551
583
});
0 commit comments