-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
쿼리 복잡도 버그 수정 및 결과 값 수정 #16
Changes from all commits
b981d63
32a7511
3fa3943
106fe42
02f0d90
bf0b2e4
590bca1
8dfebd5
d4f9b32
b592837
40748ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,18 +15,19 @@ | |
(ns com.walmartlabs.lacinia.executor | ||
"Mechanisms for executing parsed queries against compiled schemas." | ||
(:require | ||
[com.walmartlabs.lacinia.internal-utils | ||
:refer [cond-let q to-message | ||
deep-merge keepv get-nested]] | ||
[flatland.ordered.map :refer [ordered-map]] | ||
[com.walmartlabs.lacinia.select-utils :as su] | ||
[com.walmartlabs.lacinia.resolve-utils :refer [transform-result aggregate-results]] | ||
[com.walmartlabs.lacinia.schema :as schema] | ||
[com.walmartlabs.lacinia.resolve :as resolve | ||
:refer [resolve-as resolve-promise]] | ||
[com.walmartlabs.lacinia.tracing :as tracing] | ||
[com.walmartlabs.lacinia.constants :as constants] | ||
[com.walmartlabs.lacinia.selection :as selection]) | ||
[com.walmartlabs.lacinia.internal-utils | ||
:refer [cond-let q to-message | ||
deep-merge keepv get-nested]] | ||
[flatland.ordered.map :refer [ordered-map]] | ||
[com.walmartlabs.lacinia.select-utils :as su] | ||
[com.walmartlabs.lacinia.resolve-utils :refer [transform-result aggregate-results]] | ||
[com.walmartlabs.lacinia.schema :as schema] | ||
[com.walmartlabs.lacinia.resolve :as resolve | ||
:refer [resolve-as resolve-promise]] | ||
[com.walmartlabs.lacinia.tracing :as tracing] | ||
[com.walmartlabs.lacinia.constants :as constants] | ||
[com.walmartlabs.lacinia.selection :as selection] | ||
[com.walmartlabs.lacinia.query-analyzer :as query-analyzer]) | ||
(:import (clojure.lang PersistentQueue) | ||
(java.util.concurrent Executor))) | ||
|
||
|
@@ -379,15 +380,14 @@ | |
(let [parsed-query (get context constants/parsed-query-key) | ||
{:keys [selections operation-type ::tracing/timing-start]} parsed-query | ||
schema (get parsed-query constants/schema-key) | ||
^Executor executor (::schema/executor schema) | ||
complexity-warning (:complexity-warning context)] | ||
^Executor executor (::schema/executor schema)] | ||
(binding [resolve/*callback-executor* executor] | ||
(let [enabled-selections (remove :disabled? selections) | ||
*errors (atom []) | ||
*warnings (if complexity-warning | ||
(atom [complexity-warning]) | ||
(atom [])) | ||
*extensions (atom {}) | ||
*warnings (atom []) | ||
*extensions (if (::query-analyzer/enable? context) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 기존에는 execute 되기 전에 최대 복잡도를 초과하면 에러를 발생시킬 목적으로 validation 과 execute 사이에서 함수를 호출하였는데요. |
||
(atom {:analysis (query-analyzer/complexity-analysis parsed-query)}) | ||
(atom {})) | ||
*resolver-tracing (when (::tracing/enabled? context) | ||
(atom [])) | ||
context' (assoc context constants/schema-key schema) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,107 +43,127 @@ | |
[_ _ _] | ||
nil) | ||
|
||
(defn ^:private resolve-name | ||
[_ _ _] | ||
"name") | ||
|
||
(defn ^:private resolve-rooot | ||
[_ _ _] | ||
nil) | ||
|
||
(def ^:private schema | ||
(utils/compile-schema "complexity-analysis-error.edn" | ||
{:resolve-products resolve-products | ||
:resolve-followings resolve-followings | ||
:resolve-reviews resolve-reviews | ||
:resolve-likers resolve-likers | ||
:resolve-node resolve-node})) | ||
:resolve-node resolve-node | ||
:resolve-name resolve-name | ||
:resolve-root resolve-rooot})) | ||
|
||
(defn ^:private q [query variables] | ||
(utils/simplify (execute schema query variables nil {:max-complexity 10}))) | ||
(utils/simplify (execute schema query variables nil {:analyze-query true}))) | ||
|
||
(deftest over-complexity-analysis | ||
(deftest test-complexity-analysis | ||
(testing "It is possible to calculate the complexity of a query in the Relay connection spec | ||
by taking into account both named fragments and inline fragments." | ||
(is (= {:data {:node nil} | ||
:extensions {:warnings [{:message "Over max complexity! Current number of resources to be queried: 27"}]}} | ||
:extensions {:analysis {:complexity 32}}} | ||
(q "query ProductDetail($productId: ID){ | ||
node(id: $productId) { | ||
... on Product { | ||
...ProductLikersFragment | ||
seller{ | ||
id | ||
products(first: 5){ | ||
node(id: $productId) { | ||
... on Product { | ||
...ProductLikersFragment | ||
seller{ | ||
id | ||
products(first: 5){ | ||
edges{ | ||
node{ | ||
id | ||
} | ||
} | ||
} | ||
} | ||
reviews(first: 5){ | ||
edges{ | ||
node{ | ||
id | ||
author{ | ||
id | ||
name | ||
} | ||
product{ | ||
id | ||
} | ||
} | ||
} | ||
} | ||
} | ||
reviews(first: 5){ | ||
edges{ | ||
node{ | ||
} | ||
} | ||
fragment ProductLikersFragment on Product { | ||
likers(first: 10){ | ||
edges{ | ||
node{ | ||
... on Seller{ | ||
id | ||
} | ||
... on Buyer{ | ||
id | ||
author{ | ||
id | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
fragment ProductLikersFragment on Product { | ||
likers(first: 10){ | ||
edges{ | ||
node{ | ||
... on Seller{ | ||
}" {:productId "id"})))) | ||
(testing "If no arguments are passed in the query, the calculation uses the default value defined in the schema." | ||
(is (= {:data {:node nil} | ||
:extensions {:analysis {:complexity 22}}} | ||
(q "query ProductDetail($productId: ID){ | ||
node(id: $productId) { | ||
... on Product { | ||
...ProductLikersFragment | ||
seller{ | ||
id | ||
products(first: 5){ | ||
edges{ | ||
node{ | ||
id | ||
} | ||
} | ||
} | ||
} | ||
... on Buyer{ | ||
id | ||
reviews(first: 5){ | ||
edges{ | ||
node{ | ||
id | ||
author{ | ||
id | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}" {:productId "id"})))) | ||
(testing "If no arguments are passed in the query, the calculation uses the default value defined in the schema." | ||
(is (= {:data {:node nil} | ||
:extensions {:warnings [{:message "Over max complexity! Current number of resources to be queried: 22"}]}} | ||
(q "query ProductDetail($productId: ID){ | ||
node(id: $productId) { | ||
... on Product { | ||
...ProductLikersFragment | ||
seller{ | ||
id | ||
products(first: 5){ | ||
edges{ | ||
node{ | ||
id | ||
} | ||
} | ||
} | ||
} | ||
reviews(first: 5){ | ||
edges{ | ||
node{ | ||
id | ||
author{ | ||
id | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
fragment ProductLikersFragment on Product { | ||
likers{ | ||
edges{ | ||
node{ | ||
... on Seller{ | ||
id | ||
} | ||
... on Buyer{ | ||
id | ||
} | ||
} | ||
} | ||
} | ||
}" {:productId "id"}))))) | ||
fragment ProductLikersFragment on Product { | ||
likers{ | ||
edges{ | ||
node{ | ||
... on Seller{ | ||
id | ||
} | ||
... on Buyer{ | ||
id | ||
} | ||
} | ||
} | ||
} | ||
}" {:productId "id"})))) | ||
(testing "If return type of root query is scala, then complexity is 0" | ||
(is (= {:data {:root nil} | ||
:extensions {:analysis {:complexity 0}}} | ||
(q "query root{ | ||
root | ||
}" nil))))) | ||
Comment on lines
+161
to
+166
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍🏼 |
||
|
||
(comment | ||
(run-test over-complexity-analysis)) | ||
(run-test test-complexity-analysis)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@namenu 리뷰를 반영하여,
lacinia.clj execute 함수를 호출할 때 options 값에
:analyze-query
가 trucy 하다면::query-analyzer/enable?
라는 key를 context에 true로 assoc 하도록 수정하였습니다.