@@ -52,14 +52,19 @@ class GitLabDaemonImpl final : public GitLabDaemon::Server {
5252private:
5353 Config config;
5454 gitlab::GitLab gitlab;
55- cache::lru_cache<std::string, std::any> cache{20 }; // Cache for the most recent 20 calls.
55+ cache::lru_cache<std::string, gitlab::User> usercache{20 }; // Cache for the most recent 20 user calls.
56+ cache::lru_cache<std::string, gitlab::Group> groupcache{40 }; // Cache for the most recent 40 group calls.
5657 std::map<gitlab::GroupID, gid_t > groupMap;
5758
59+ template <typename V>
60+ cache::lru_cache<std::string, V>& getcache ();
61+
5862 template <typename T>
5963 bool findInCache (const std::string& cacheId, T& value) {
64+ auto & cache = getcache<T>();
6065 if (cache.exists (cacheId)) {
6166 spdlog::info (" Found in cache" );
62- if (const T* val = std::any_cast<T>( &cache.get (cacheId) )) {
67+ if (const T* val = &cache.get (cacheId)) {
6368 value = *val;
6469 return true ;
6570 } else {
@@ -99,129 +104,156 @@ class GitLabDaemonImpl final : public GitLabDaemon::Server {
99104public:
100105 GitLabDaemonImpl (Config config) : config(config), gitlab(this ->config), groupMap(resolveGroupMap()) {}
101106
102- virtual ::kj::Promise<void > getUserByID (GetUserByIDContext context) override {
103- spdlog::info (" getUserByID({})" , context.getParams ().getId ());
104- auto cacheId = std::format (" getUserByID({})" , context.getParams ().getId ());
105- gitlab::User user;
106- Error err = Error::Ok;
107- if (findInCache (cacheId, user) ||
108- ((err = gitlab.fetchUserByID (context.getParams ().getId (), user)) == Error::Ok &&
109- (err = gitlab.fetchGroups (user)) == Error::Ok)) {
110- spdlog::debug (" Found" );
111- cache.put (cacheId, user);
112- auto output = context.getResults ().initUser ();
113- output.setId (user.id );
114- output.setName (user.name );
115- output.setUsername (user.username );
116- output.setState (user.state );
117- auto groups = output.initGroups (user.groups .size ());
118- for (auto i = 0 ; i < user.groups .size (); ++i) {
119- if (decltype (groupMap)::iterator it; (it = groupMap.find (user.groups [i].id )) != groupMap.end ()) {
120- // Group mapped to host group
121- groups[i].setId (it->second );
122- groups[i].setName (" " );
123- groups[i].setLocal (true );
124- } else {
125- // GitLab group
126- groups[i].setId (user.groups [i].id );
127- groups[i].setName (user.groups [i].name );
128- groups[i].setLocal (false );
129- }
107+ virtual ::kj::Promise<void > getUserByID (GetUserByIDContext context) override ;
108+ virtual ::kj::Promise<void > getUserByName (GetUserByNameContext context) override ;
109+ virtual ::kj::Promise<void > getSSHKeys (GetSSHKeysContext context) override ;
110+ virtual ::kj::Promise<void > getGroupByID (GetGroupByIDContext context) override ;
111+ virtual ::kj::Promise<void > getGroupByName (GetGroupByNameContext context) override ;
112+ };
113+
114+ template <>
115+ constexpr cache::lru_cache<std::string, gitlab::User>& GitLabDaemonImpl::getcache<gitlab::User>() {
116+ return usercache;
117+ }
118+ template <>
119+ constexpr cache::lru_cache<std::string, gitlab::Group>& GitLabDaemonImpl::getcache<gitlab::Group>() {
120+ return groupcache;
121+ }
122+
123+ ::kj::Promise<void > GitLabDaemonImpl::getUserByID (GetUserByIDContext context) {
124+ auto & cache = getcache<gitlab::User>();
125+ spdlog::info (" getUserByID({})" , context.getParams ().getId ());
126+ auto cacheId = std::format (" getUserByID({})" , context.getParams ().getId ());
127+ gitlab::User user;
128+ Error err = Error::Ok;
129+ if (findInCache (cacheId, user) || ((err = gitlab.fetchUserByID (context.getParams ().getId (), user)) == Error::Ok &&
130+ (err = gitlab.fetchGroups (user)) == Error::Ok)) {
131+ spdlog::debug (" Found" );
132+ cache.put (cacheId, user);
133+ cache.put (std::format (" getUserByName({})" , user.name ), user);
134+ auto output = context.getResults ().initUser ();
135+ output.setId (user.id );
136+ output.setName (user.name );
137+ output.setUsername (user.username );
138+ output.setState (user.state );
139+ auto groups = output.initGroups (user.groups .size ());
140+ for (auto i = 0 ; i < user.groups .size (); ++i) {
141+ if (decltype (groupMap)::iterator it; (it = groupMap.find (user.groups [i].id )) != groupMap.end ()) {
142+ // Group mapped to host group
143+ groups[i].setId (it->second );
144+ groups[i].setName (" " );
145+ groups[i].setLocal (true );
146+ } else {
147+ // GitLab group
148+ groups[i].setId (user.groups [i].id );
149+ groups[i].setName (user.groups [i].name );
150+ groups[i].setLocal (false );
130151 }
131152 }
132- context.getResults ().setErrcode (static_cast <uint32_t >(err));
133- return kj::READY_NOW;
134153 }
135- virtual ::kj::Promise<void > getUserByName (GetUserByNameContext context) override {
136- spdlog::info (" getUserByName({})" , context.getParams ().getName ().cStr ());
137- auto cacheId = std::format (" getUserByName({})" , context.getParams ().getName ().cStr ());
138- gitlab::User user;
139- Error err = Error::Ok;
140- if (findInCache (cacheId, user) ||
141- ((err = gitlab.fetchUserByUsername (context.getParams ().getName ().cStr (), user)) == Error::Ok &&
142- (err = gitlab.fetchGroups (user)) == Error::Ok)) {
143- spdlog::debug (" Found" );
144- cache.put (cacheId, user);
145- auto output = context.getResults ().initUser ();
146- output.setId (user.id );
147- output.setName (user.name );
148- output.setUsername (user.username );
149- output.setState (user.state );
150- auto groups = output.initGroups (user.groups .size ());
151- for (auto i = 0 ; i < user.groups .size (); ++i) {
152- if (decltype (groupMap)::iterator it; (it = groupMap.find (user.groups [i].id )) != groupMap.end ()) {
153- // Group mapped to host group
154- groups[i].setId (it->second );
155- groups[i].setName (" " );
156- groups[i].setLocal (true );
157- } else {
158- // GitLab group
159- groups[i].setId (user.groups [i].id );
160- groups[i].setName (user.groups [i].name );
161- groups[i].setLocal (false );
162- }
154+ context.getResults ().setErrcode (static_cast <uint32_t >(err));
155+ return kj::READY_NOW;
156+ }
157+ ::kj::Promise<void > GitLabDaemonImpl::getUserByName (GetUserByNameContext context) {
158+ auto & cache = getcache<gitlab::User>();
159+ spdlog::info (" getUserByName({})" , context.getParams ().getName ().cStr ());
160+ auto cacheId = std::format (" getUserByName({})" , context.getParams ().getName ().cStr ());
161+ gitlab::User user;
162+ Error err = Error::Ok;
163+ if (findInCache (cacheId, user) ||
164+ ((err = gitlab.fetchUserByUsername (context.getParams ().getName ().cStr (), user)) == Error::Ok &&
165+ (err = gitlab.fetchGroups (user)) == Error::Ok)) {
166+ spdlog::debug (" Found" );
167+ cache.put (cacheId, user);
168+ cache.put (std::format (" getUserByID({})" , user.id ), user);
169+ auto output = context.getResults ().initUser ();
170+ output.setId (user.id );
171+ output.setName (user.name );
172+ output.setUsername (user.username );
173+ output.setState (user.state );
174+ auto groups = output.initGroups (user.groups .size ());
175+ for (auto i = 0 ; i < user.groups .size (); ++i) {
176+ if (decltype (groupMap)::iterator it; (it = groupMap.find (user.groups [i].id )) != groupMap.end ()) {
177+ // Group mapped to host group
178+ groups[i].setId (it->second );
179+ groups[i].setName (" " );
180+ groups[i].setLocal (true );
181+ } else {
182+ // GitLab group
183+ groups[i].setId (user.groups [i].id );
184+ groups[i].setName (user.groups [i].name );
185+ groups[i].setLocal (false );
163186 }
164187 }
165- context.getResults ().setErrcode (static_cast <uint32_t >(err));
166- return kj::READY_NOW;
167188 }
189+ context.getResults ().setErrcode (static_cast <uint32_t >(err));
190+ return kj::READY_NOW;
191+ }
168192
169- virtual ::kj::Promise<void > getSSHKeys (GetSSHKeysContext context) {
170- spdlog::info (" getSSHKeys({})" , context.getParams ().getId ());
171- std::vector<std::string> keys;
172- Error err;
173- if ((err = gitlab.fetchAuthorizedKeys (context.getParams ().getId (), keys)) == Error::Ok) {
174- spdlog::debug (" Found" );
175- // When std::ranges::to is finally implemented by GCC:
176- // std::string joined = keys | std::views::join | std::ranges::to<std::string>();
177- std::string joined;
178- for (auto && key : keys)
179- joined += key + " \n " ;
193+ ::kj::Promise<void > GitLabDaemonImpl:: getSSHKeys (GetSSHKeysContext context) {
194+ spdlog::info (" getSSHKeys({})" , context.getParams ().getId ());
195+ std::vector<std::string> keys;
196+ Error err;
197+ if ((err = gitlab.fetchAuthorizedKeys (context.getParams ().getId (), keys)) == Error::Ok) {
198+ spdlog::debug (" Found" );
199+ // When std::ranges::to is finally implemented by GCC:
200+ // std::string joined = keys | std::views::join | std::ranges::to<std::string>();
201+ std::string joined;
202+ for (auto && key : keys)
203+ joined += key + " \n " ;
180204
181- context.getResults ().setKeys (joined);
182- }
183- context.getResults ().setErrcode (static_cast <uint32_t >(err));
184- return kj::READY_NOW;
205+ context.getResults ().setKeys (joined);
185206 }
207+ context.getResults ().setErrcode (static_cast <uint32_t >(err));
208+ return kj::READY_NOW;
209+ }
186210
187- virtual ::kj::Promise<void > getGroupByID (GetGroupByIDContext context) override {
188- spdlog::info (" getGroupByID({})" , context.getParams ().getId ());
189- auto cacheId = std::format (" getGroupByID({})" , context.getParams ().getId ());
190- gitlab::Group group;
191- Error err = Error::Ok;
192- if (findInCache (cacheId, group) ||
193- (err = gitlab.fetchGroupByID (context.getParams ().getId (), group)) == Error::Ok) {
194- spdlog::debug (" Found" );
195- cache.put (cacheId, group);
196- auto output = context.getResults ().initGroup ();
197- output.setId (group.id );
198- output.setName (group.name );
199- }
200- context.getResults ().setErrcode (static_cast <uint32_t >(err));
201- return kj::READY_NOW;
211+ ::kj::Promise<void > GitLabDaemonImpl::getGroupByID (GetGroupByIDContext context) {
212+ auto & cache = getcache<gitlab::Group>();
213+ spdlog::info (" getGroupByID({})" , context.getParams ().getId ());
214+ auto cacheId = std::format (" getGroupByID({})" , context.getParams ().getId ());
215+ gitlab::Group group;
216+ Error err = Error::Ok;
217+ if (findInCache (cacheId, group) || (err = gitlab.fetchGroupByID (context.getParams ().getId (), group)) == Error::Ok) {
218+ spdlog::debug (" Found" );
219+ cache.put (std::format (" getGroupByName({})" , group.name ), group);
220+ cache.put (cacheId, group);
221+ auto output = context.getResults ().initGroup ();
222+ output.setId (group.id );
223+ output.setName (group.name );
202224 }
203- virtual ::kj::Promise<void > getGroupByName (GetGroupByNameContext context) override {
204- spdlog::info (" getGroupByName({})" , context.getParams ().getName ().cStr ());
205- auto cacheId = std::format (" getGroupByName({})" , context.getParams ().getName ().cStr ());
206- gitlab::Group group;
207- Error err = Error::Ok;
208- if (findInCache (cacheId, group) ||
209- (err = gitlab.fetchGroupByName (context.getParams ().getName ().cStr (), group)) == Error::Ok) {
210- spdlog::debug (" Found" );
211- cache.put (cacheId, group);
212- auto output = context.getResults ().initGroup ();
213- output.setId (group.id );
214- output.setName (group.name );
215- }
216- context.getResults ().setErrcode (static_cast <uint32_t >(err));
217- return kj::READY_NOW;
225+ context.getResults ().setErrcode (static_cast <uint32_t >(err));
226+ return kj::READY_NOW;
227+ }
228+ ::kj::Promise<void > GitLabDaemonImpl::getGroupByName (GetGroupByNameContext context) {
229+ auto & cache = getcache<gitlab::Group>();
230+ spdlog::info (" getGroupByName({})" , context.getParams ().getName ().cStr ());
231+ auto cacheId = std::format (" getGroupByName({})" , context.getParams ().getName ().cStr ());
232+ gitlab::Group group;
233+ Error err = Error::Ok;
234+ if (findInCache (cacheId, group) ||
235+ (err = gitlab.fetchGroupByName (context.getParams ().getName ().cStr (), group)) == Error::Ok) {
236+ spdlog::debug (" Found" );
237+ cache.put (cacheId, group);
238+ cache.put (std::format (" getGroupByID({})" , group.id ), group);
239+ auto output = context.getResults ().initGroup ();
240+ output.setId (group.id );
241+ output.setName (group.name );
218242 }
219- };
243+ context.getResults ().setErrcode (static_cast <uint32_t >(err));
244+ return kj::READY_NOW;
245+ }
220246
221247static auto [promise, fulfiller] = kj::newPromiseAndFulfiller<void >();
222248int main (int argc, char * argv[]) {
223- // Daemonize
224- daemon (0 , 0 );
249+ bool daemonize = true ;
250+ if (argc == 2 && argv[1 ] == std::string_view{" --foreground" }) {
251+ daemonize = false ;
252+ } else if (argc != 1 ) {
253+ return -1 ; // Invalid CLI Args
254+ }
255+ if (daemonize)
256+ daemon (0 , 0 );
225257 {
226258 std::ofstream fstream ((std::filesystem::absolute (" run" ) / " gitlabnssd.pid" ).c_str ());
227259 fstream << getpid () << std::endl;
0 commit comments