Fork me on GitHub
#graphql
<
2018-06-07
>
hiredman00:06:39

I have been chasing concurrency gremlins in a project, and after trace logging I see resolvers returning values that never seem to get delivered to the promise returned from execute-parsed-query-async, I have a patched version of com.walmartlabs.lacinia.resolve/resolve-promise that seems to fix it, should I submit a pr? I don't have a small reproducible test case for it

hlship21:06:46

Thanks for submitting, may look at this today.

hlship16:06:55

Looks good, though if you look at the implementation of Promise, I'm surprised it makes a difference.

hiredman17:06:44

I am not sure what you mean by Promise? If you mean clojure.core/promise the issue is using two promises without coordination between them. if one thread runs on-deliver! up to line 156, then in the middle there another thread runs all of deliver! up to line 174, then both threads miss each other

hlship17:06:36

Well, maybe we can do a short cycle to get that into an early 0.28.0 rc.

hiredman17:06:24

that would be super. I haven't figured out what I want to do until this fix is upstreamed, I've got plenty of other issues to deal with, and we have direct linking turned on for deployments, so money patching is tricky

hlship18:06:27

Well, you could easily do a local fork with a variation of the artifact name.

hlship18:06:54

I'll want to see if there's performance impact from this change but it probably needs to go in either way, for correctness.

hlship18:06:12

But it's going to be terrible to test, like all concurrency issues.

eggsyntax19:06:13

Are there any known/common issues with lacinia and concurrency? & if so, is there documentation anywhere re dealing with it? When several requests are made in rapid succession, I end up with lacinia/execute throwing some pretty weird errors, eg

{:message "Exception applying arguments to field `chart_data': For argument `chart_params', for input string: \".2201071717E4.2201071717E4\"", :query-path [], :locations [{:line 1, :column 0}], :field :chart_data, :argument :chart_params, :value "2017-10-01", :type-name :Date}
That looks like several of those date values are getting interleaved. I can solve it without much trouble by putting lacinia/execute behind a global queue, and executing queries one at a time, but of course there are possible perf costs there. If there are existing patterns around lacinia & concurrency, I'd love to get a pointer to them. And of course it could turn out that this is unrelated to lacinia -- but at first sniff that seems the most likely. Thanks!

hiredman19:06:02

what do you mean by interleaved?

eggsyntax19:06:58

Just that if you compare ".2201071717E4.2201071717E4" to "2017-10-01" it looks suspiciously like the former is being built from multiple, interleaved copies of the latter, along with some other bit of data. Could be totally wrong; I'm just hard-put to see where else that bizarre string could be coming from.

hiredman19:06:36

oh, you are likely using SimpleDateFormat to parse the date, and that class isn't thread safe

eggsyntax19:06:08

Ah, bingo, bet that's it. Thanks @hiredman, nice catch!

eraserhd19:06:35

oh man, I've spent several hours debugging exactly that problem, probably three times in my career.

eggsyntax19:06:02

Yeah, I feel really lucky that someone just headed me off at the pass šŸ˜„

eggsyntax19:06:16

Those lacinia errors are still a bit opaque to me -- just out of being new to them -- so it probably would have taken me a painfully long time to realize that it was about the val being passed to the date parser.

eggsyntax19:06:55

(plus I didn't realize that SDF is non-thread-safe šŸ˜Š )

nrako19:06:38

I see this in the docs -

By convention, the built-in scalar types are identified as symbols, such as {:type String}. Other types (objects, interfaces, enums, and unions) are identified as keywords, {:type (list :character)}. It actually makes no difference; internally everything is converted to keywords in the compiled schema.
Does this mean that {:type list(:Int)} is viable in a schema.edn file? Just want to confirm that I am understanding this correctly.

hiredman19:06:29

that isn't valid edn

nrako19:06:41

Hmmā€¦ gotcha. Presumably ignoring the typo {:type (list :Int)}ā€¦ thanksā€¦

hlship20:06:39

{:type (list Int)} and {:type (list :Int)} are exactly the same, just a matter of personal preference.

hlship20:06:46

Internally, the first is converted to the second.

hlship20:06:23

Everything is a keyword in the compiled schema.

nrako20:06:04

I see. So it is valid. Many thanksā€¦

mattly21:06:14

Iā€™m trying to use a tool to generate schema docs from an introspection query and itā€™s giving me this error back:

mattly21:06:46

does this look like something that should be supported?

mattly22:06:05

or is the tool assuming a particular implementation of the server?

hlship22:06:14

I'll have to research that; our directives support is not very good and it's quite likely we're missing something there.

mattly22:06:15

man the javascript ecosystem is garbage

mattly22:06:45

ā€œuse our simple static GraphQL doc generatorā€ ā€¦ ā€œstep 10, install webpackā€

hlship22:06:46

I'm an outsider looking in there, but it feels like a bit of chaos. Plus it's alien (how modules are downloaded, documented, etc.). JS devs who come to Clojure and Java are likely equally unimpressed.

mattly22:06:32

I just tried another tool and got the same exact error

mattly23:06:54

would you like me to file an issue?