ChanServ changed the topic of #crystal-lang to: The Crystal programming language | | Fund Crystal's development: | GH: | Docs: | Gitter:
ur5us has quit [Ping timeout: 264 seconds]
ur5us has joined #crystal-lang
ur5us has quit [Ping timeout: 248 seconds]
ur5us has joined #crystal-lang
Starfoxxes has quit [Ping timeout: 252 seconds]
walez has joined #crystal-lang
Starfoxxes has joined #crystal-lang
ur5us has quit [Ping timeout: 248 seconds]
renich has quit [Quit: Leaving]
<repo> Blacksmoke16: I started a new pet-project with athena, avram and graphql. I've told you this many times, but once again: kudos for athena. It's so well designed. I love it <3
ur5us has joined #crystal-lang
<repo> I discovered a major drawback in the graphql shard though (not yours, i know): It's not possible to use a dataloader. Furthermore, i haven't seen any dataloader implementation in crystal... It would seem to be quite straight forward since the good fiber support in crystal. I think the hard part is to make the graphql resolver resolve fields asynchronously.
sagax has joined #crystal-lang
ur5us has quit [Ping timeout: 268 seconds]
Sankalp- has joined #crystal-lang
Sankalp has quit [Ping timeout: 264 seconds]
Sankalp- is now known as Sankalp
jmdaemon has quit [Ping timeout: 268 seconds]
walez has quit [Read error: Connection reset by peer]
walez has joined #crystal-lang
<FromGitter> <Blacksmoke16> 💪 thanks dude, glad to hear :)
<FromGitter> <Blacksmoke16> unfortunately i never used graphql so im not sure what that means xD
ox is now known as oz
<repo> heh :)
<repo> well since you have great freedom in what you query (e.g. author { books { publisher { name } } }) you really quickly end up with N+1 queries (like in my example because you will query the publisher for each book instead of all publishers with any of the book ids.
<repo> this is where dataloaders come into play. They batch the db requests. They usually have a #load(id) method or something similar, which adds the id to a batch. After a "while" (say a millisecond or so) the loader then calls a batch loading function you have to implement for each loader with all ids that have been requested. The #load function waits until the batch loading is done and picks the
<repo> result from the array of results from the batch loading.
<FromGitter> <Blacksmoke16> is that something you could make a PR for? :P
<repo> where?
<repo> i think a dataloader would have to be an own shards
<repo> -s
<FromGitter> <Blacksmoke16> deff sounds like it would be useful. never really thought about N+1 query stuff in graphql tho. makes sense since you dont have control over the queries (or do you?)
<FromGitter> <Blacksmoke16> oh its not part of graphql itself?
<repo> no it's not
<repo> yeah you don't really have control over the queries
<FromGitter> <Blacksmoke16> ahh gotcha gotcha
<repo> authorization is also fun :D
<repo> i could make a pull request which would parallelize the resolving of fields in graphql
<repo> this would be a prequisite for this to work, because the load(id) calls have to happen in parallel.
<FromGitter> <Blacksmoke16> by parallel im assuming you mean via fibers? parallel would require the MT flag
<repo> yeah fibers
<repo> concurrently :)
<FromGitter> <Blacksmoke16> afaik if you implement that correctly it should just work when MT becomes the default (or is enabled by the user)
<FromGitter> <Blacksmoke16> could be a nice win too
<repo> it should work in any case. doesn't need MT.
<FromGitter> <Blacksmoke16> could be worth it yea
<FromGitter> <Blacksmoke16> which shard are you using for it?
<repo> for graphql?
<repo> graphql-ruby/graphql
<FromGitter> <Blacksmoke16> yea
<repo> sorry
<repo> graphql-crystal/graphql
<repo> :D
<FromGitter> <Blacksmoke16> gg
<repo> i think, it was that one. :P
<repo> yeah
<FromGitter> <Blacksmoke16> is also idk what they diff between them is tho
<FromGitter> <Blacksmoke16> looks much older
<repo> yeah
<repo> graphql-crystal/graphql seemed more mature
<repo> here the logic would have to change
<FromGitter> <Blacksmoke16> and btw, if you haven't seen, might be helpful if you're really only using the routing features versus DI and all that other stuff
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <Blacksmoke16> wew thats a good chunk of macro code
<repo> yeah i looked at it but i needed DI anyway :)
<repo> yeah :D
<FromGitter> <Blacksmoke16> 👍
<repo> alternatively (maybe that's even easier to do) one could return a Promise (there's a shard for that) and then one would just have to add a case here:
<repo> which could just resolve the promise and call the same method with the result
<repo> ah no
<repo> it'd still be sequential
<FromGitter> <Blacksmoke16> if you just want to run things concurrently would prob have to use fibers/channels
<FromGitter> <Blacksmoke16> like spawn them all then in some method do like `n.times { yield results.receive }`
<FromGitter> <Blacksmoke16> or instead of yielding, create an array of each result and return it once they're all done?
<repo> yeah.
<FromGitter> <Blacksmoke16> related:
rez has joined #crystal-lang
walez has quit [Quit: Leaving]
_ht has joined #crystal-lang
<FromGitter> <rjnienaber> is there anything like the using directive ( from C# in Crystal? I'm trying modulize my classes correctly (e.g. `Amazonite::DynamoDB::AttributeDefinition`) but in practice it starts to get a bit repetitive.
<FromGitter> <Blacksmoke16> in some (most?) cases you can prob get away with just using `AttributeDefinition`
<FromGitter> <Blacksmoke16> esp when you're already within a type in he `Amazonite::DynamoDB` namespace
<yxhuvud> You can also use alias to create a short-form of a longer definition
<FromGitter> <Blacksmoke16> otherwise you could use private aliases
<FromGitter> <Blacksmoke16> ^ yea, for some of my stuff i expose some aliases on the top level that can be used to avoid the first two part of the type into a 3 or 4 letter name
<FromGitter> <Blacksmoke16> the bottom part of that post at least
<FromGitter> <rjnienaber> that's definitely close to what I'm thinking of. Would it be possible to write a macro that is the equivalent of `private alias ScalarAttributeType = Amazonite::DynamoDB::*` ?
<FromGitter> <Blacksmoke16> you'd inherently have that already as `private alias ScalarAttributeType = Amazonite::DynamoDB`
<FromGitter> <Blacksmoke16> ``
<FromGitter> <rjnienaber> that's for a single type though, right? In my scenario, there would be a need for many `alias` statements so i'm trying to avoid having 20 lines of declarations at the top of the file. Something more akin to how `require "./core/*"` works, but for bringing in all the types of a namespace
<FromGitter> <rjnienaber> sorry if i'm incorrectly mixing up terminology
<FromGitter> <Blacksmoke16> right ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ or are you thinking of something else? []
<FromGitter> <rjnienaber> At the moment I have this: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ which works but I can see that list of aliases being a lot longer []
<FromGitter> <Blacksmoke16> id so something like: ⏎ ⏎ ```private alias ADB = Amazonite::DynamoDB ⏎ ⏎ ADB:: ScalarAttributeType ⏎ ADB::KeyType``` []
<FromGitter> <Blacksmoke16> would be the simplest approach id say. doesnt allow you to use each type's name directly, but helps a lot
<FromGitter> <Blacksmoke16> could prob write some macro to like iterate thru the types to generate the private aliases but :shrug:
<FromGitter> <rjnienaber> that's perfect!
<FromGitter> <rjnienaber> thank you :)
<FromGitter> <Blacksmoke16> 👍 np
_ht has quit [Remote host closed the connection]
ur5us has joined #crystal-lang
fifr has joined #crystal-lang
jmdaemon has joined #crystal-lang
notzmv has quit [Ping timeout: 248 seconds]
Starfoxxes has quit [Ping timeout: 252 seconds]
ur5us has quit [Ping timeout: 264 seconds]
Starfoxxes has joined #crystal-lang