Skip to content

Commit

Permalink
avoid linear search in roles lookup: get-roles time 4ms -> 1ms
Browse files Browse the repository at this point in the history
If there was no DB access, it would be even faster: 0.001ms
  • Loading branch information
luontola committed Apr 12, 2019
1 parent f3db6ea commit c75e0a1
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 15 deletions.
10 changes: 5 additions & 5 deletions src/clj/rems/api/applications_v2.clj
Expand Up @@ -87,15 +87,15 @@
(fn [state events]
;; Because enrich-with-injections is not idempotent,
;; it's necessary to hold on to the "raw" applications.
(let [raw-apps (reduce all-applications-view (:raw-apps state) events)
(let [raw-apps (reduce all-applications-view (::raw-apps state) events)
updated-app-ids (distinct (map :application/id events))
cached-injections (map-vals memoize injections)
enriched-apps (->> (select-keys raw-apps updated-app-ids)
(map-vals #(model/enrich-with-injections % cached-injections))
(merge (:enriched-apps state)))]
{:raw-apps raw-apps
:enriched-apps enriched-apps})))
:enriched-apps
(merge (::enriched-apps state)))]
{::raw-apps raw-apps
::enriched-apps enriched-apps})))
::enriched-apps
(vals)))

(defn get-all-applications [user-id]
Expand Down
32 changes: 22 additions & 10 deletions src/clj/rems/db/dynamic_roles.clj
Expand Up @@ -11,15 +11,21 @@
(update applications app-id model/calculate-permissions event)
applications))

(defn- roles-of-user [user applications-by-id]
(defn- group-roles-by-user [applications-by-id]
(->> applications-by-id
(vals)
(map #(permissions/user-roles % user))
(apply set/union)))
(mapcat (fn [app] (::permissions/user-roles app)))
(reduce (fn [roles-by-user [user roles]]
(update roles-by-user user set/union roles))
{})))

(defn- get-user-roles [user roles-by-user]
(get roles-by-user user #{}))

(defn- roles-from-all-applications [user events]
(->> (reduce permissions-of-all-applications nil events)
(roles-of-user user)))
(group-roles-by-user)
(get-user-roles user)))

(deftest test-roles-from-all-applications
(let [events [{:event/type :application.event/created
Expand All @@ -29,16 +35,22 @@
{:event/type :application.event/created
:event/actor "applicant-and-handler"
:application/id 2}]]
(is (= #{:applicant :everyone-else}
(is (= #{:applicant}
(roles-from-all-applications "applicant-only" events)))
(is (= #{:applicant :handler}
(roles-from-all-applications "applicant-and-handler" events)))))
(roles-from-all-applications "applicant-and-handler" events)))
(is (= #{}
(roles-from-all-applications "unknown" events)))))

(mount/defstate dynamic-roles-cache
:start (events-cache/new))

(defn get-roles [user]
(->> (events-cache/refresh! dynamic-roles-cache
(fn [applications events]
(reduce permissions-of-all-applications applications events)))
(roles-of-user user)))
(->> (events-cache/refresh!
dynamic-roles-cache
(fn [state events]
(let [apps (reduce permissions-of-all-applications (::apps state) events)]
{::apps apps
::roles-by-user (group-roles-by-user apps)})))
::roles-by-user
(get-user-roles user)))

0 comments on commit c75e0a1

Please sign in to comment.