<FromGitter>
<js:nil.im> first google result is old
<FromGitter>
<js:nil.im> the newer one has something
<FromGitter>
<js:nil.im> would it be a good idae to add a banner to old documentation pointing out that you are looking at old documentation and a link to the current one?
<FromGitter>
<js:nil.im> ah, thx. Never heard of that one before
<FromGitter>
<oprypin:matrix.org> > I usually look up the stuff that I need as I go π β β i'm not messing around, like seriously, it's really short and you'll just know everything
<FromGitter>
<js:nil.im> hmm, maybe a good idea. I thought it was too much to read it one go, but given the recommendation, I suppose it can't be that long π
<FromGitter>
<js:nil.im> hmm, I noticed that there's `property :foo` and `property foo` in the docs. Which one is preferred? And apparently there's also `property @foo`
<FromGitter>
<js:nil.im> the last_reload is not something that should have a setter
<FromGitter>
<Blacksmoke16> why not just `Setting.new(@static_hosts, ...)`?
<FromGitter>
<js:nil.im> but if you dup, it should make it to the copy
<FromGitter>
<js:nil.im> oh, you mean have a new, private initializer?
<FromGitter>
<Blacksmoke16> sure
<FromGitter>
<js:nil.im> because currently none of those are in the initializer, as they are all parsed from configs
<FromGitter>
<Blacksmoke16> are you sure you need to define `dup` tho? Pretty it should just work
<FromGitter>
<Blacksmoke16> yaml config?
<FromGitter>
<js:nil.im> system config
<FromGitter>
<js:nil.im> and yes, I need the dup - I need to keep the config as of the moment I sent the query
<FromGitter>
<js:nil.im> if the config changes in between, it still needs to be performed with the old settings
<FromGitter>
<Blacksmoke16> https://play.crystal-lang.org/#/r/ahol i mean this, `dup` is already defined. Just returns the same obj but with a diff obj id
<FromGitter>
<js:nil.im> if I don't define it I get an error :/
<FromGitter>
<js:nil.im> maybe I should figure out why that is instead
<FromGitter>
<js:nil.im> oh, it was a missing type π
<FromGitter>
<js:nil.im> I had @settings = settings.dup
<FromGitter>
<js:nil.im> and it could not infer the type from that
<FromGitter>
<js:nil.im> if I added @settings : Settings, it works
<FromGitter>
<Blacksmoke16> mhm
<FromGitter>
<Blacksmoke16> its better to be explicit imo
<FromGitter>
<js:nil.im> something else I'm not getting from the documentation: If I declare a block as part of the arguments, can I capture it *and* yield it?
<FromGitter>
<js:nil.im> Basically, the block would be `Response | Error`
<FromGitter>
<js:nil.im> on error, I could yield early
<FromGitter>
<js:nil.im> (for some, that is)
<FromGitter>
<js:nil.im> but for others, I'd need to capture it and call it later
<FromGitter>
<Blacksmoke16> prob something to do with blocks or something
<FromGitter>
<js:nil.im> that was my guess, too
<FromGitter>
<js:nil.im> that the compiler cannot prove the block gets called
<FromGitter>
<js:nil.im> anyway, the error in this case an also come from the nameserver
<FromGitter>
<js:nil.im> what I do in my ObjC code is have an exception, but I don't throw it, I pass it around as an error argument
<FromGitter>
<Blacksmoke16> but regarding your thing, disregard what i said, as they're the yielded arguments, not the response
<FromGitter>
<Blacksmoke16> also unless you're using fibers, passing a capture block around isn't technically async. It would be more like delaying the invocation of the code
<FromGitter>
<js:nil.im> I suppose there will be fibers as soon as I use sockets
<FromGitter>
<Blacksmoke16> π
<FromGitter>
<js:nil.im> otherwise the non-blocking DNS resolver will, well, not be non-blocking π
<FromGitter>
<js:nil.im> ok, pushed my current state
<FromGitter>
<js:nil.im> the goal is definitely to get this into a state where it can be part of stdlib, to have non-blocking DNS lookups in Crystal π
<FromGitter>
<Blacksmoke16> this would help with your other issue, i.e. `context.id` versus `context.@id`
<FromGitter>
<Blacksmoke16> as majority of the time you really shouldnt be accessing internal state like that
<FromGitter>
<Blacksmoke16> `super(name, DNSClass::IN, RRType::A, ttl)` symbols are autocasted to enum members. So could do something like `super name, :in, :a, ttl` Just something to keep in mind/save some keystrokes
<FromGitter>
<js:nil.im> what's preferred? consistency with the enum name or the lowercase symbols convention?
<FromGitter>
<Blacksmoke16> i usually use lower snake case
<FromGitter>
<Blacksmoke16> e.g. `:foo` or `:some_key` for `Foo` and `SomeKey`
richbridger has joined #crystal-lang
<FromGitter>
<js:nil.im> but enums are always upper, aren't they?
<FromGitter>
<Blacksmoke16> they have to start with a capital letter. I never know how i want to have them :/
<FromGitter>
<Blacksmoke16> they're technically constants, but not really constants :shrug:
<FromGitter>
<js:nil.im> ah, I just noticed that if I use the symbol trick, I need to put the type in the initializer. So just putting it to the property doesn't work
<FromGitter>
<Blacksmoke16> they're equivalent, mainly was just making you aware. Is up to you on which you want to use
<FromGitter>
<js:nil.im> I mean, having to add more types is a downside ;)
<FromGitter>
<Blacksmoke16> if you say so
<FromGitter>
<js:nil.im> is it preferred to repeat types everywhere?
<FromGitter>
<Blacksmoke16> to me yes, esp if it's something you're planning on making public. As the only thing you're saving is a few keystrokes
<FromGitter>
<Blacksmoke16> thats my preferred style yea, but im sure others have their own opinions on it
skrzyp has joined #crystal-lang
<FromGitter>
<oprypin:matrix.org> type inference is still done. type restrictions only *restrict* the allowed outcomes.
<FromGitter>
<oprypin:matrix.org> im nitpicking here though
<FromGitter>
<oprypin:matrix.org> > shouldn't the documentation use the compiler and use the inferred types to fix that? β β generally it's super hard to correctly automatically collapse whatever was inferred to a declaration that is readable
<FromGitter>
<oprypin:matrix.org> it could just turn out wrongly inferred. say a function is only ever used with one type but actually it can accept any type
<FromGitter>
<HertzDevil> > that I had at first, but then it complained about id being read before being set β β that's because `loop` creates a new scope and `while` doesn't
<FromGitter>
<HertzDevil> you could do `while false` and any variables declared within will still be accessible afterwards, only that they'll be nil
_ht has joined #crystal-lang
robertmeta_ has joined #crystal-lang
issyl0_ has joined #crystal-lang
avane_ has joined #crystal-lang
oprypin_ has joined #crystal-lang
lanodan_ has joined #crystal-lang
oprypin has quit [*.net *.split]
avane has quit [*.net *.split]
robertmeta has quit [*.net *.split]
FromGitter has quit [*.net *.split]
issyl0 has quit [*.net *.split]
lanodan has quit [*.net *.split]
robertmeta_ is now known as robertmeta
issyl0_ is now known as issyl0
avane_ is now known as avane
FromGitter has joined #crystal-lang
hendursa1 has joined #crystal-lang
hendursaga has quit [Ping timeout: 268 seconds]
<FromGitter>
<asterite> Also, to capture a block and yield it, you don't use yield: you use call on the block
<frojnd>
pp vs puts was also interesting while learning crystal
richbridger has quit [Ping timeout: 256 seconds]
postmodern has quit [Quit: Leaving]
bougyman has quit [Excess Flood]
bougyman has joined #crystal-lang
<FromGitter>
<Blacksmoke16> There's also p and p! Iirc
<FromGitter>
<erdnaxeli:cervoi.se> and pp!
deavmi has quit [Ping timeout: 258 seconds]
deavmi has joined #crystal-lang
_ht has quit [Remote host closed the connection]
_ht has joined #crystal-lang
teardown has quit [Ping timeout: 268 seconds]
teardown has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
lanodan_ is now known as lanodan
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
fifr` has quit [Ping timeout: 245 seconds]
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
fifr` has joined #crystal-lang
HumanG33k has quit [Ping timeout: 276 seconds]
<FromGitter>
<roduquen> Hi everyone, I got an issue with websocket server that I don't get between Crystal and js, I do a simple ws server : β β ```ws = WebSocket.new("ws://localhost:5060/");``` β β I got : Firefox canβt establish a connection to the server at ws://localhost:5060/ ... [https://gitter.im/crystal-lang/crystal?at=60411c79d71b6554cd2004e8]
<FromGitter>
<roduquen> I never had this error in 0.35.1 and have already 3 websockets server running on aws with 0.35.1, I don't know if it is about 0.36.1
HumanG33k has joined #crystal-lang
richbridger has joined #crystal-lang
<FromGitter>
<roduquen> Does anyone ever meet this issue ?
<FromGitter>
<Blacksmoke16> i assume you're using the same host and port in both cases?
<FromGitter>
<Blacksmoke16> could try making the host like `"0.0.0.0"`
<FromGitter>
<roduquen> yep I use this host
<straight-shoota>
what's `WebSocket.handler()`?
<straight-shoota>
Maybe try some other browsers or websocket client, maybe you can get some debug info (or try to see what's going on in firefox)
<FromGitter>
<jrei:matrix.org> this way it is clear what address is used
<hightower2>
Hey friends, just a nice success - for a customer I had to rewrite some python stuff to be more performant (some code which combines http, rabbit, and redis). The desired target was to achieve 1M requests per hour. Even without -Dpreview_mt, the end result was 2.5M requests/hour.
<straight-shoota>
nice
<straight-shoota>
however, it might just be a testimony that Python's inefficiency was accepted as normal :D
<FromGitter>
<jrei:matrix.org> great :)
<FromGitter>
<jrei:matrix.org> what was the previous actual rate per hour?
<straight-shoota>
Btw. multithreading might not really make a web app faster. Likely even worse than running multiple single-thread processes.
<hightower2>
jrei: was interested in it myself too, but hard to tell... in the end didn't get figures from them, and didn't bother to check myself
<hightower2>
will report just for info in case I hear about it tomorrow
<hightower2>
straight-shoota, right, that was my other plan... haproxy is already in front of everything, so easy job to just multiply workers
<straight-shoota>
you can also just use SO_REUSEPORT
<hightower2>
yes, yes, but it's distributed across multiple machines etc., so
<hightower2>
plus haproxy is used for a ton of stuff other than just pure load balancing (ddos protection, retries, ssl, rate limiting, etc.)
<straight-shoota>
yeah, but on each machine you can use that. they'll likely have multiple CPU cores, right? =)
<straight-shoota>
so you go haproxy -> port on worker instances -> multple processes with SO_REUSEPORT
<hightower2>
ah yes, that's a nice trick too, even though there's no control which process will take it. So retries, which they always send to a different process, may land on the same one multiple times
<straight-shoota>
if haproxy distributes over different instances...
<hightower2>
that's a good idea, I'll think about it some more, thanks
<FromGitter>
<jrei:matrix.org> Multi process would be better
<FromGitter>
<jrei:matrix.org> Multi thread don't scale linearily
<FromGitter>
<jrei:matrix.org> Plus, it won't be as stable β it is still a preview
<straight-shoota>
yeah, the last few comments were about whether multiplexing on a single machine happens over SO_REUSEPORT or if just every process is a separate backend for haproxy (with its own port)
<FromGitter>
<jrei:matrix.org> I just read about SO_REUSEPORT and what it does.
<FromGitter>
<jrei:matrix.org> Sound better to let HAProxy do the dispatch instead of the machine's OS
<FromGitter>
<jrei:matrix.org> The main thing I've in mind is healthcheck
<FromGitter>
<roduquen> @jrei:matrix.org Thanks, I got this when I do the puts on logs 'Board WebSocket Server Listening on 0.0.0.0:5060', I always use puts I never took time to read logs I have them in my docker logs on aws... I guess it should probably be better to use Log API.. I don't remember the way to go through crystal master instead of regular
<FromGitter>
<roduquen> And I didn't get the listen on ::1, the same on aws happened, the address is "wss://dev.wss.remotings.com:5060"
<FromGitter>
<roduquen> It works with Crystal WebSocket Client API but JS WebSocket API still not succeed to connect
<FromGitter>
<roduquen> (I meant I don't know what means listen on ::1)
<FromGitter>
<jrei:matrix.org> You're on docjer?
<hightower2>
roduquen localhost on ipv6
<FromGitter>
<roduquen> Locally not but on AWS yep
<FromGitter>
<jrei:matrix.org> Try the basic example from the API docs
fifr` has quit [Ping timeout: 260 seconds]
<FromGitter>
<jrei:matrix.org> Or a similar basic one. Of it works, you can start from there
<FromGitter>
<roduquen> it is on a module but no classes
<FromGitter>
<roduquen> I wrote new servers in a more functionnal way
<FromGitter>
<roduquen> But I guess it couldn't be an issue
<FromGitter>
<roduquen> I ll try through Chrome to check
<FromGitter>
<roduquen> Same issue, I can't get to the connection I tried https://www.websocket.org/echo.html, with the address and can't connect, when with the websocket client from crystal I can
<FromGitter>
<jrei:matrix.org> Also why are you putting the method name in case of an exception
<FromGitter>
<roduquen> I don't really know my logs are really bad globally
<FromGitter>
<jrei:matrix.org> It will be already present in the trace with `exception.inspect_with_backtrace`
<FromGitter>
<roduquen> I spend more time spamming travis with new puts
<FromGitter>
<jrei:matrix.org> (I recommend to put this in STDERR)
<FromGitter>
<roduquen> Oh well
<FromGitter>
<roduquen> :facepalm:
<FromGitter>
<jrei:matrix.org> You're on what OS?
<FromGitter>
<roduquen> Ubuntu
<FromGitter>
<roduquen> 1) 04
<FromGitter>
<roduquen> same on AWS
<FromGitter>
<roduquen> the dockers are running on CENTOS but on aws ubuntu 20.04
<FromGitter>
<roduquen> (I meant I created the EC2 on ubuntu but dockers are running through centos, I use bintray docker for crystal)
<FromGitter>
<roduquen> ```code paste, see link``` β β like a simple one β I guess it is the most reproductible environment I can give my computer is not the most setted up I use to try online directly because of ssl [https://gitter.im/crystal-lang/crystal?at=604138c9d71b6554cd205e7d]
<FromGitter>
<jrei:matrix.org> and with a simple HTTP server?
<FromGitter>
<roduquen> Works fine
<FromGitter>
<jrei:matrix.org> O.o
<FromGitter>
<roduquen> There is also an HTTP server listening on 5020 on the same service
<FromGitter>
<roduquen> With exactly the same pattern
<FromGitter>
<roduquen> Just not on websocket
<FromGitter>
<jrei:matrix.org> you can have the ws and HTTP on the same port
<FromGitter>
<jrei:matrix.org> websocket is http, at least at the beginning
<FromGitter>
<roduquen> Oh ok I didn't know I separated everything on terraform
<FromGitter>
<jrei:matrix.org> I've a case/when, which either serve the API or ws
<FromGitter>
<roduquen> Oh ok like this, cause I try the idiot way doing both servers on same ports I got ```Unhandled exception in spawn: Could not bind to '0.0.0.0:5020': Address already in use (Socket::BindError) β from /usr/share/crystal/src/socket/addrinfo.cr:75:15 in 'initialize:reuse_port' β from /usr/share/crystal/src/socket/tcp_server.cr:32:3 in 'new:reuse_port' β from /usr/share/crystal/src/http/server.cr:211:5
<FromGitter>
<roduquen> But could connect now even if the normal server isn't running now
<FromGitter>
<roduquen> I meant the HTTP normal
<FromGitter>
<roduquen> Is 5060 a bad port I ll try an other lol
<FromGitter>
<roduquen> No unfortunately, but what I can see is only one server running and it accepts websocket connection
<FromGitter>
<roduquen> from Firefox
<FromGitter>
<roduquen> And in any cases Crystal WebSocket client works
HumanG33k has quit [Ping timeout: 260 seconds]
<FromGitter>
<roduquen> really weird, when I launch only one server on 5020, the websocket ones, I cant connect through firefox, when I try to launch both on 5020, the restful one crashes but I can connect to the websocket one
<FromGitter>
<roduquen> I tried to inverse the spawn but did nothing
<FromGitter>
<roduquen> And it works really lol
<FromGitter>
<roduquen> When the first one crashes
<FromGitter>
<roduquen> I guess the first one even if spawned influenced the websocket once, in a good and bad way at the same time
<FromGitter>
<roduquen> When crashes it works, when not here it doesn't work
<FromGitter>
<roduquen> Well I think I go through the problem step by step, When not here I let the require
<FromGitter>
<roduquen> But without that require of restful one, I could connect through websocket
<FromGitter>
<roduquen> And what is different from my others services with 2 servers HTTP/ws, is kemal
HumanG33k has joined #crystal-lang
<FromGitter>
<roduquen> I ll erase all kemal stuffs on the HTTP one, and try again and I will tell you when done, but I will eat fastly I'll ping you to know if the problem was here
<FromGitter>
<roduquen> (I tried to use kemal just to not do the get/post etc by myself by the way ^^')
fifr` has joined #crystal-lang
fifr` has quit [Ping timeout: 260 seconds]
<FromGitter>
<Luj8n> Hey! How can you get the instance of the struct/class inside that class? Idk how to ask, but in javascript there is `this` keyword
<FromGitter>
<Blacksmoke16> `self`?
<FromGitter>
<Luj8n> hmm
<FromGitter>
<Luj8n> yeah
<FromGitter>
<Luj8n> i thought that self.something was like a static method
<FromGitter>
<Blacksmoke16> `def self.something` is a class method
<FromGitter>
<Luj8n> yeah
<FromGitter>
<Blacksmoke16> but `self` can either mean the instance, or the class depending on the context of where it's used
<FromGitter>
<Luj8n> oh
<FromGitter>
<Luj8n> thanks so much!
<FromGitter>
<Blacksmoke16> e.g. if you use `self` within a class method its a reference to the class
<straight-shoota>
in class context, class is the instance
<straight-shoota>
(kindof)
<frojnd>
I Would like to measure my operation of writing data into db. What functions, classess hould I use?
<frojnd>
One would expect this would be 365, but no it gives false: `days = Time.leap_year? 2021 ? 366 : 365` I had to use parenthesis: `days = (Time.leap_year? 2021) ? 366 : 365`
<FromGitter>
<jrei:matrix.org> prefer to use `Time.leap_year?(2021)`
<FromGitter>
<Blacksmoke16> and?
<FromGitter>
<Blacksmoke16> ^, yea this is kinda expected and is a case where you need the `()`
<frojnd>
I see
<FromGitter>
<jrei:matrix.org> will be still ambiguous even if it worked
<frojnd>
I never kno when to use method arg vs method(arg) now I know :D
<FromGitter>
<jrei:matrix.org> at times I'd like to have `expr if true else false`. `expr if true` already works
<frojnd>
Am I reading this righ? "dbexec: 00:00:05.300371454" this is 5 seconds
<FromGitter>
<Blacksmoke16> yes
<frojnd>
And this is "dbquery: 00:00:00.001585947" well quick..
<FromGitter>
<jrei:matrix.org> why?
<straight-shoota>
1.4 ms for sounds reasonable a simple query
fifr` has quit [Ping timeout: 276 seconds]
<FromGitter>
<js:nil.im> How does one best handle avoiding to accidentally return something from a function?
<FromGitter>
<watzon:matrix.org> Example?
<FromGitter>
<js:nil.im> Say, my function calls another function which returns something
<FromGitter>
<js:nil.im> but I don't want to return anything
<FromGitter>
<watzon:matrix.org> Just do `function_call; nil`
<FromGitter>
<watzon:matrix.org> I mean technically you're always returning something, but in this case you return `nil`
<FromGitter>
<js:nil.im> is there a way to declare that as the type and get an error if I accidentally return someting?
<FromGitter>
<js:nil.im> def foo : Nil?
<FromGitter>
<watzon:matrix.org> Just `def foo : Nil` would do. The question mark is redundant.
<FromGitter>
<js:nil.im> well, the question mark was not supposed to be part of it π
<FromGitter>
<js:nil.im> it was because it was a question - I should have used ` around it
<FromGitter>
<watzon:matrix.org> Lmao
<FromGitter>
<watzon:matrix.org> Then yes
hendursa1 has quit [Quit: hendursa1]
hendursaga has joined #crystal-lang
<FromGitter>
<Blacksmoke16> well to be clear if you do `def foo : Nil`, you wont get an error if it returns something other than `nil`, as the compiler makes it always return `nil`
<FromGitter>
<watzon:matrix.org> Right. `def foo : Nil` would be for if you just want to make sure the function you're wrapping is returning `nil`.
<FromGitter>
<Daniel-Worrall> Wouldn't it be a compiler error that the last line *could* return non-nil?
<FromGitter>
<Blacksmoke16> diff method, but same problem
<FromGitter>
<js:nil.im> oh ffs, name is another propery name I use
<FromGitter>
<Blacksmoke16> well that has been fixed i think, and was a class method
<FromGitter>
<Blacksmoke16> so prob not a problem now
<FromGitter>
<js:nil.im> *phew*
<FromGitter>
<js:nil.im> is `type` another dangerous name?
<FromGitter>
<Blacksmoke16> idt
<FromGitter>
<watzon:matrix.org> `type` is fine from my experience
<FromGitter>
<watzon:matrix.org> I use it all the time
<FromGitter>
<watzon:matrix.org> The ones I'd stay away from are the legit keywords. class, struct, module, enum, def, abstract, private, and macro are the only ones I can think of off the top of my head.
<FromGitter>
<js:nil.im> can I also set default values when I use the `record` macro?
<FromGitter>
<watzon:matrix.org> Yep
<FromGitter>
<watzon:matrix.org> `record Foo, bar : String = "baz"`
<FromGitter>
<js:nil.im> perfect, thx! π
HumanG33k has quit [Remote host closed the connection]