ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.24.2 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
<FromGitter> <stern0> Back to my question. Do fibers use just one core or can use multiple cores
<FromGitter> <j8r> One, that's the principle
<FromGitter> <j8r> You can have concurency in one core, unless a process use 100% CPU time
<FromGitter> <j8r> If this happen, all will be slowed of course
<FromGitter> <straight-shoota> @stern0 You said it yourself, Crystal has no multithreading support yet. So all fibers are on only one core at the time.
g-glitch has quit [Remote host closed the connection]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 256 seconds]
<FromGitter> <Blacksmoke16> having an issue merging hashes
<FromGitter> <Blacksmoke16> where when i go to merge it gives me a variable must be Hash(String, ...)
<FromGitter> <Blacksmoke16> ```code paste, see link``` ⏎ ⏎ Where the type is just has everything twice [https://gitter.im/crystal-lang/crystal?at=5aea699c00dc4888048eac42]
<FromGitter> <bew> The type after `not` is much longer
<FromGitter> <Blacksmoke16> yes it has everything twice
<FromGitter> <bew> Not exactly twice, the second one can embed the first one (in addition to everything else)
<FromGitter> <Blacksmoke16> only happens when using a instance variable, local variable works fine
<FromGitter> <bew> Whats your code?
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5aea6a6e53ceca3604a994d4]
<FromGitter> <Blacksmoke16> where path.construct_obj is
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5aea6ad15cf0b8300450cf2f]
<FromGitter> <bew> to ease the readability, you can do `@paths.each do |(path_url, responses)| ...`
<FromGitter> <Blacksmoke16> ah noice
<FromGitter> <bew> what is the `PathObjBody` type ?
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5aea6b816f9af87e043b1ce7]
<FromGitter> <Blacksmoke16> end result looks like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5aea6ba359a05780049e33ff]
<FromGitter> <bew> instead of `@endpoints = @endpoints.merge(s)` you can do `@endpoints.merge!(s)` (with a bang `!`) to mutate the hash directly without creating a new one
<FromGitter> <bew> in `construct_obj`, instead of making a lot of `@obj[path_name][...]` you can save `@obj[path_name]` in a local var, and use it (less `Hash#[]` call the better :) )
<FromGitter> <bew> like `@obj[path_name] = my_hash = {} of String => PathObjBody`
<FromGitter> <bew> and use `my_hash` later, it'll be the same as doing `@obj[path_name]` each time
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5aea6d55f2d2d537045b95ab]
<FromGitter> <bew> why your hash in this method is not a class btw?
<FromGitter> <bew> with description, parameters, path, scope, summary & version
<FromGitter> <Blacksmoke16> it is i just excluded it from the paste
<FromGitter> <Blacksmoke16> its in the one up a bit
<FromGitter> <bew> I mean, why build a hash instead of build an object?
<FromGitter> <Blacksmoke16> hm good question
<FromGitter> <Blacksmoke16> probably could do
<FromGitter> <bew> and to get back to your problem, you're trying to merge a `Hash(String, PathObjBody)` with a `Hash(String, Hash(String, PathObjBody))`
<FromGitter> <j8r> How can improve this? `caddy.sections[0] = caddy.sections[0].merge({root: "/path"}) `
<FromGitter> <bew> @Blacksmoke16 the merged type is `Hash(String, PathObjBody | Hash(String, PathObjBody))`, with the alias expanded
<FromGitter> <bew> that the error you got, 'cause you're trying to store that type in `@endpoints` which is `Hash(String, PathObjBody)` only
<FromGitter> <bew> @j8r what are the types here?
<FromGitter> <bew> oh just use `merge!` ?
<FromGitter> <bew> to mutate the thing directly
<FromGitter> <bew> instead of building a new one
<FromGitter> <bew> (if it's a hash or sth)
<FromGitter> <Blacksmoke16> why would it work as a local variable tho?
<FromGitter> <bew> @Blacksmoke16 I guess it's because the local variable happily accept any type, and is not constrained to a specific type
<FromGitter> <Blacksmoke16> i could go with that
<FromGitter> <Blacksmoke16> makes sense
<FromGitter> <j8r> @bew don't work for NamedTuple: https://carc.in/#/r/3zou
<FromGitter> <Blacksmoke16> call `to_h` on it?
<FromGitter> <j8r> lol, no
<FromGitter> <bew> huh no @Blacksmoke16, no other way, you *have to* build a new one @j8r
<FromGitter> <Blacksmoke16> welp
<FromGitter> <j8r> But this annoyance is only for `String`
<FromGitter> <j8r> e.g. https://carc.in/#/r/3zp0
rohitpaulk has joined #crystal-lang
<FromGitter> <j8r> I can do `klass.section[0][:test]["a"] = "C"` but not `klass.section[0][:root] = "C"`
rohitpaulk has quit [Ping timeout: 260 seconds]
<FromGitter> <girng> i love me some namedtuples
<FromGitter> <bew> @j8r yeah that's normal, string are immutable, so you need to modify the namedtuple to change it
<FromGitter> <bew> but the hash is mutable, you can change the hash without having to make a new one
duper has quit [Remote host closed the connection]
wmoxam has quit [Remote host closed the connection]
<FromGitter> <Blacksmoke16> @bew i refactored/rearranged some stuff so that the hash is now an object, and the @endpoints property is an array of that obj
<FromGitter> <Blacksmoke16> thinking i can then just use a custom to_json to parse that array into the format i need
<FromGitter> <bew> a mapping you mean?
<FromGitter> <Blacksmoke16> mm sec
<FromGitter> <Blacksmoke16> had a change of thought
<FromGitter> <Blacksmoke16> yea nvm,
<FromGitter> <Blacksmoke16> refactored it to use an obj and did `property endpoints = {} of String => EndpointObj`
<FromGitter> <Blacksmoke16> which i update by doing `@endpoints.merge!(s)`
<FromGitter> <Blacksmoke16> im happy with it
<FromGitter> <Blacksmoke16> hardest part is figuring out what to call all these :(
<FromGitter> <Blacksmoke16> i also just realized there was absolutely no point of me creating the hash array for parameters, since it was literally just an around about way of doing Parameter.to_h
<FromGitter> <Blacksmoke16> updated code
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5aea82cf53ceca3604a9cdbc]
<FromGitter> <bew> note: `x.merge!({y => z})` is the same as `x[y] = z`
<FromGitter> <bew> (but does't create a temporary hash)
<FromGitter> <Blacksmoke16> which is better? ⏎ `@endpoints.merge!({path.operationId.gsub(/get_|_id/, "") => EndpointObj.new(path.description, path.parameters, path_url, path.scope, path.responses.success.description)})` ⏎ or like ⏎ `@endpoitns[path.operationId.gsub(/get_|_id/, "")] = EndpointObj.new(path.description, path.parameters, path_url, path.scope, path.responses.success.description)`
<FromGitter> <bew> last one
<FromGitter> <bew> simply doing `{y => z}` will create a hash
<FromGitter> <bew> and you don't need a hash, you just want to set a value I think
<FromGitter> <Blacksmoke16> correct
<FromGitter> <Blacksmoke16> makes sense, one less hash so be more performant
<FromGitter> <Blacksmoke16> here's a question, now that im using `Hash(String, EndpointObj)` as my endpoints variable, what if i needed to get the whole hash into json?
<FromGitter> <Blacksmoke16> should just be able to make a custom to_json on the EndpointObj class?
<FromGitter> <bew> yeah with a mapping
<FromGitter> <bew> (for example)
<FromGitter> <Blacksmoke16> also does inline if/unless not handle nil values? such as `@scopes << path.scope unless path.scope.nil?` yells saying scopes is string only while that is String | Nil
<FromGitter> <galvertez> if that condition would ever return true during runtime then the type would be `String|Nil` regardless wouldn't it?
<FromGitter> <Blacksmoke16> probably but shouldnt matter because the insert should never happen if it is nil?
<FromGitter> <bew> the same way it does with a normal if
<FromGitter> <bew> maybe `path.scope` will return something else on the second call
<FromGitter> <bew> you probably want `if scope = path.scope; @scopes << scope; end`
<FromGitter> <bew> this way only one call to `path.scope` is made
<FromGitter> <bew> and that result (which we know won't change) is inserted in `@scopes`
<FromGitter> <galvertez> would using `#nil?` not add Nil to the type inference? JSON.mapping is just a macro it's not the final word on that instance variable's type
<FromGitter> <bew> @galvertez hmm no? you can do `a = true; a.nil?; typeof(a)` it'll be `Bool`
<FromGitter> <bew> `nil?` is just a method call, it doesn't do anything else
<FromGitter> <bew> the compiler is just smart about `nil?` in conditions to *reduce* the type when it can
<FromGitter> <Multipixelone> Okay so I have an array named "chocolate" How can I add everything in the array into a text file, on separate lines?
<FromGitter> <bew> you could open a file, then for each element of the array: write the element to the file, then add a newline, until the end of the array
<FromGitter> <bew> it's an array of strings?
rohitpaulk has joined #crystal-lang
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5aea8f8fb982f08504eca929]
<FromGitter> <Blacksmoke16> something like so
<FromGitter> <Blacksmoke16> er chocolates.txt*
rohitpaulk has quit [Ping timeout: 248 seconds]
<FromGitter> <Multipixelone> Okay
<FromGitter> <Multipixelone> Ill see if that works
<FromGitter> <bew> yes, but `file.puts s`
<FromGitter> <Multipixelone> Yeah that makes sense
<FromGitter> <Blacksmoke16> yea file.puts s works as well
<FromGitter> <Blacksmoke16> nice
<FromGitter> <Multipixelone> Thanks man 😄
<FromGitter> <Blacksmoke16> nn
Nathanaelle has joined #crystal-lang
johndescs_ has joined #crystal-lang
johndescs has quit [Ping timeout: 276 seconds]
johndescs_ is now known as johndescs
<FromGitter> <galvertez> i haven't figured out what `%` does in an example like this https://github.com/crystal-lang/crystal/blob/master/src/json/mapping.cr#L101- i don't see it documented in gitbook but i see it in a few places
<FromGitter> <galvertez> perfect
<FromGitter> <galvertez> ty
<FromGitter> <bew> in this case it's used to make sure that the method will not conflict with another method with the same arguments
<FromGitter> <galvertez> yeah. as soon as i read the title in the url all the examples i've seen made so much more sense lol!
<FromGitter> <galvertez> actually i have been avoiding macros in some cases because i didn't know this was an option. this is great
<FromGitter> <JannAnthonyBriza> Having these problem already did `shards install`
<FromGitter> <JannAnthonyBriza> kind a weird it was running yesterday :(
<FromGitter> <bew> what's the full error? (the useful bits are at the bottom)
<FromGitter> <JannAnthonyBriza> wait i'll try to screenshot the whole error, cause it does not fit in screenshot
<FromGitter> <bew> no need to screenshot, just copy/paste the error to a pastebin or sth!
<FromGitter> <JannAnthonyBriza> oh wait i this this is the problem ` /home/jann/.cache/crystal/usr-share-crystal-src-ecr-process.cr/macro_run: error while loading shared libraries: libevent-2.0.so.5: cannot open shared object file: No such file or directory`
<FromGitter> <bew> yes!
<FromGitter> <JannAnthonyBriza> yes i need to find this library `libevent-2.0.so.5:`
<FromGitter> <bew> how did you installed crystal?
<FromGitter> <JannAnthonyBriza> git this error when i upgraded my linux os from 16.04 to 18.04
<FromGitter> <JannAnthonyBriza> i will try to uninstall my crystal
<FromGitter> <bew> When you install it yourself, make sure you install all required libraries, https://github.com/crystal-lang/crystal/wiki/All-required-libraries#ubuntu
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 264 seconds]
<FromGitter> <faustinoaq> @JannAnthonyBriza Just try to search a similar file in your system using `sudo find / -iname "*libevent-2.0.so*"` and then create a symlink to it using `sudo ln -s /path/to/available/lib/libevent-2.0.so.X /usr/lib/libevent-2.0.so.5`
<FromGitter> <faustinoaq> this is a common issue on dynamic linked executable's, sometimes the `.so` dependencies have version mismatch, although, commonly you can just point your missing lib to the available version in your system 😅
<FromGitter> <faustinoaq> Also ensure first you have the right libs installed like @bew said
<FromGitter> <Multipixelone> If I don't know how to do something, where is the best place to look? The API documentation seems pretty bare
<FromGitter> <Multipixelone> Most of my learning has been "How do I do this in Ruby?" "Does it work in Crystal?" "Great!"
<FromGitter> <epergo> crystal for rubyist by sdogruyol is a good resource to learn
<FromGitter> <hmans> Gooood morning Crystal \o/
<FromGitter> <gdotdesign> Morning :)
rohitpaulk has joined #crystal-lang
<FromGitter> <sdogruyol> morning everyone
<FromGitter> <sdogruyol> thanks @epergo 👍
<FromGitter> <oprypin> @faustinoaq manually putting anything in /usr/lib basically means breaking your system. don't recommend people to break their system.
Ven`` has joined #crystal-lang
Ven`` has quit [Read error: Connection reset by peer]
Ven`` has joined #crystal-lang
<wuehlmaus> say, i have the file "/etc/passwd". How do i get the creation time? with fileinfo i don't find the answer.
<wuehlmaus> File.info("/etc/passwd") has st_ctimespec=LibC::Timespec
sz0 has quit [Quit: Connection closed for inactivity]
Ven`` has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
rohitpaulk has quit [Ping timeout: 256 seconds]
rohitpaulk has joined #crystal-lang
<FromGitter> <sdogruyol> what'd be the most idiomatic way of running something periodically
<FromGitter> <sdogruyol> for example EventMachine has ⏎ ⏎ ```EM::PeriodicTimer.new(5, do_something) # Runs do_something every 5 secs``` [https://gitter.im/crystal-lang/crystal?at=5aeae8dfb37eab7d0463ec23]
<FromGitter> <sdogruyol> guess combining some kind of loop with `delay`?
<FromGitter> <gdotdesign> in a fiber of course
<FromGitter> <sdogruyol> legit 👍 @gdotdesign
<crystal-gh> [crystal] sdogruyol closed pull request #6038: Remove SemanticVersion (master...remove-semantic-version) https://git.io/vp0mf
rohitpaulk has quit [Ping timeout: 276 seconds]
rohitpaulk has joined #crystal-lang
<FromGitter> <gdotdesign> how can I construct a `Hash(String, String | Int32)` from `{ "test" => "test"}`? Because the latter will just be `Hash(String, String)` which gives a type error, casting it does not help either.
<FromGitter> <gdotdesign> right now I'm doing this `{ "test" => "test", "" => 0}` which feels like a hack
<FromGitter> <yxhuvud> `{ "test" => "test"} of String => String|Int32` or something like that.
<FromGitter> <gdotdesign> yes! that works thank you :D
alex`` has quit [Quit: WeeChat 2.1]
alex`` has joined #crystal-lang
alex`` is now known as alexherbo2
alexherbo2 is now known as alex``
<FromGitter> <Blacksmoke16> @bew adding a JSON mapping worked perfect
<FromGitter> <Blacksmoke16> thats super slick
<FromGitter> <Blacksmoke16> is there a way to override the `setter: true` default behavior of JSON.mapping?
rohitpaulk has quit [Ping timeout: 255 seconds]
rohitpaulk has joined #crystal-lang
<FromGitter> <Qwerp-Derp> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5aeb0175b37eab7d04644991]
Raimondi has quit [Quit: WeeChat 1.9.1: ¡Chau!]
<FromGitter> <Qwerp-Derp> There's a workaround in #3349 but no one's tried to fix it
<DeBot> https://github.com/crystal-lang/crystal/issues/3349 (Surprising error with generic abstract base class)
rohitpaulk has quit [Ping timeout: 248 seconds]
rohitpaulk has joined #crystal-lang
<07IACYQVD> [crystal] ysbaddaden closed pull request #5946: Fix link in openssl.cr (master...patch-12) https://git.io/vpeTx
<DeBot> https://github.com/crystal-lang/crystal/pull/5946 (Fix link in openssl.cr)
<17SAA34KB> crystal/master 5e518f9 r00ster: Fix link to full ciphers list in openssl.cr (#5946)
<17SAA34KB> [crystal] ysbaddaden pushed 1 new commit to master: https://git.io/vp2IO
<DeBot> https://github.com/crystal-lang/crystal/pull/5946 (Fix link in openssl.cr)
<FromGitter> <faustinoaq> @oprypin oh, ok 👍 😅
<FromGitter> <faustinoaq> @oprypin What do you do when your have version mismatch on dynamic libs? (`.so` files) ? 😅
Raimondi has joined #crystal-lang
<FromGitter> <schoening> Crystals concurrency is inspired by Go right? So wouldn't it perhaps also have made sense to have go style error returns? This is just a random question out of interest..
<FromGitter> <faustinoaq> @schoening I guess crystal is inspired by ruby as well 😉
<FromGitter> <schoening> Hehe yeah I guess that is the answer I expected 😄
<travis-ci> crystal-lang/crystal#5e518f9 (master - Fix link to full ciphers list in openssl.cr (#5946)): The build passed. https://travis-ci.org/crystal-lang/crystal/builds/374396867
<DeBot> https://github.com/crystal-lang/crystal/pull/5946 (Fix link in openssl.cr)
<FromGitter> <hmans> You expected correctly!
<FromGitter> <hmans> :b
<FromGitter> <hmans> I'm going to https://rubyunconf.eu/ this weekend and thinking about doing a talk on Crystal
<FromGitter> <hmans> But I sort of hate myself for that, because most talks in most Ruby meetups/conferences over here nowadays are about stuff that is not actually Ruby.
<FromGitter> <sdogruyol> awesome @hmans
<FromGitter> <sdogruyol> do you want to have a pair review of your talk maybe?
<FromGitter> <sdogruyol> I could help with that
<FromGitter> <hugoabonizio> @hmans it's true! but the ruby community was never scared of trying new technology
shalmezad has joined #crystal-lang
<FromGitter> <straight-shoota> and because of the huge similarity but still different concepts, you get a new perspective on Ruby.
<FromGitter> <straight-shoota> knowing how things work in Crystal helps getting better at Ruby
<FromGitter> <straight-shoota> and vice versa
<z64> +1 ^
<FromGitter> <yxhuvud> Yeah especially the type checks on nilability.
<FromGitter> <j8r> Crystal is a bit like a superset of Ruby - except there isn't really backward compatibility with Ruby
<FromGitter> <hmans> @sdogruyol I have not prepared anything yet, and that may be the problem overall -- it's a very last minute thing, and I'm busy with a project... so I don't know if it'll happen.
<FromGitter> <hmans> I would probably mostly talk about a side project I'm doing with Crystal, my reasons for using Crystal for it, etc.
<FromGitter> <sdogruyol> @hmans I see, I think that's also OK
<FromGitter> <j8r> @hmans what is the project :-) ?
duane has joined #crystal-lang
<FromGitter> <hmans> @j8r The project that's keeping me too busy to write talks, or the one I'm doing with Crystal? The latter is https://github.com/hmans/crankypants (example: http://cranky.hmans.io/)
<FromGitter> <hmans> It's not terribly exciting at this point, just a very fast dynamically served blog
<FromGitter> <hmans> The intent is to do some Indieweb things. Mmmm. Indieweb things.
<FromGitter> <hmans> My talk, if I do one, would be roughly about how we're achieving static site-level performance while still rendering things dynamically on the server (off a 64 MB VM), thanks to the magic combination of Crystal and SQLite
shalmezad has quit [Ping timeout: 276 seconds]
<FromGitter> <j8r> How dynamic is it? Is there an API for dynamic stuff, or all the page is re-rendered for each request à la PHP?
shalmezad has joined #crystal-lang
<FromGitter> <hmans> This may sound a bit weird, but there are reasons why I'm doing it: it has both. The user-facing blog at / is completely server-rendered. But there's also an /api/ that powers a Vue app (at /app/) that you use for interacting with your site.
<FromGitter> <hmans> But the stuff that you can see at / (without logging in at /app) is 100% purely server-side. I'm fetching stuff from SQlite, rendering it through Slang. Routing is done by my own little nanoframework.
<FromGitter> <hmans> The framework, if you're interested, is at https://github.com/hmans/crankypants/blob/master/src/crappy.cr (I once wrote a similar thing for Ruby called Happy, and this is Crystal Happy... hence... the... name... yeah)
<FromGitter> <hmans> Crappy's take on routing request is to basically just tackle it imperatively (instead of decoupling routing and request processing like most routing frameworks do.)
<FromGitter> <j8r> If I'm correct, SSR (server side rendering) in e.g. React/Vue is done once buy the server, an rendered as a static HTML?
<FromGitter> <hmans> I don't do JS SSR
<FromGitter> <hmans> The server-side rendering is pure Crystal.
<FromGitter> <j8r> Oh Ok all is done on server
<FromGitter> <hmans> This is the part that renders the public-facing blog: https://github.com/hmans/crankypants/blob/master/src/crankypants/web/handler.cr#L32-L43
<FromGitter> <j8r> But you aren't afraid to have perf penality (even if Crystal is blasing fast)?
<FromGitter> <hmans> @j8r Individual pages render in under 1ms. I'm afraid of nothing
<FromGitter> <j8r> Haha ok
<FromGitter> <hmans> With network round trip, I'm looking at around 35ms to fetch a complete page off the server.
<FromGitter> <j8r> Maybe I say this because configuring caches like Varnish & co for PHP/Java etc is a nightmare
<FromGitter> <hmans> Server-side rendering gives me machine readability, though, which is ultra-crucial on the web (especially when engaging in IndieWeb protocols.)
<FromGitter> <hmans> The instance on cranky.hmans.io can currently serve almost 1400req/s off a 1 core, 64 MB (!) VM
<FromGitter> <j8r> Yep, but how about scaling - is there an API?
<FromGitter> <hmans> I'm happy to couple it with an nginx service to do some load balancing, reverse proxying, the likes... but no need so far
<FromGitter> <hmans> I'm not sure if I understand your question.
<FromGitter> <j8r> You can have one Vue.js front app with multiple back-ends
<FromGitter> <hmans> Yes, crankypants has a REST API. I'm just confused how that ties into scaling?
<FromGitter> <j8r> nvm that's when we separate front/back (I've thinked so becasue you talked about Vue.js)
<FromGitter> <j8r> That's also useful to separate front/back for: creating a application in Android/iOS, and when we want to refactor the back code
<FromGitter> <j8r> but I agree: it's simpler to write all in server
<FromGitter> <j8r> like PHP do
<FromGitter> <j8r> micro services bring advantages but adds complexity :-/
<FromGitter> <hmans> Yeah, as mentioned before... the way you (as the site owner) interact with the app is through a Vue app that talks to a JSON API. It's all ready to be used from remote clients.
<FromGitter> <hmans> / serves a public-facing blog, /api a JSON API, and /app a Vue app that consumes the API.
<FromGitter> <j8r> why hybrid? Why not all server rendered, or all statically rendered?
<FromGitter> <j8r> just curious :-)
<FromGitter> <gdotdesign> server rendered is much better for SEO
<FromGitter> <gdotdesign> for the admin interface it doesn't matter much
<FromGitter> <gdotdesign> crankypants seems nice :) 👍
<FromGitter> <j8r> but you can do SSR with Vue, maybe done here
<FromGitter> <gdotdesign> for that you need Node on the server for sites like blogs and news ones it does't makes sense to me to build an SPA
<FromGitter> <j8r> meh :-/
<FromGitter> <j8r> Personally I use Vue.js prerendering
<FromGitter> <j8r> nothing can beat static HTML :-)
<FromGitter> <girng> did someone say nodejs
<FromGitter> <r00ster91> what about adding a link at https://crystal-lang.org/api/0.24.2/HTTP/Server/Response.html#content_type to see all possible content types that can be specified?
<oprypin> r00ster91, it would be an infinite list
<FromGitter> <r00ster91> huh really? i would find this link helpful https://www.iana.org/assignments/media-types/media-types.xhtml
<FromGitter> <girng> does this effect crystal's development in any way?
<FromGitter> <hmans> Doing JS SSR would not allow me to run on a 64 MB VM.
<FromGitter> <j8r> and what about pre rendering?
<FromGitter> <hmans> (There is a specific reason why I'm doing this, and I'm looking forward *very much* to blogging more about what I'm doing and why)
<FromGitter> <hmans> Holy crap, that LLVM drama
<FromGitter> <bew> @girng don't think so
<crystal-gh> [crystal] veelenga opened pull request #6055: Useless assigns (master...fix/useless-assigns) https://git.io/vp2KJ
greengriminal has joined #crystal-lang
Ven`` has joined #crystal-lang
<FromGitter> <hmans> Anyone interfacing with ImageMagick or similar yet?
Ven`` has quit [Read error: Connection reset by peer]
<FromGitter> <hmans> Ah, I'm seeing https://github.com/imdrasil/crymagick. Nice.
<FromGitter> <hmans> I'm assuming Process.run pauses at least the current fiber, right?
<FromGitter> <hmans> Or does it pause more?
<FromGitter> <hmans> The API reference just says "Executes a process and waits for it to complete."
<FromGitter> <girng> yeah but if its in its own fiber, it's rather fast should be ok
<FromGitter> <hmans> As long as it doesn't halt the entire process, it's all good. I will give it a try
<FromGitter> <girng> i use to get output data from `top`, works rather cool
Jenz has joined #crystal-lang
<FromGitter> <j8r> from top?!
* Jenz is happy
<FromGitter> <j8r> maybe you can now use https://crystal-community.github.io/hardware/index.html
<FromGitter> <j8r> PIDs are know supported
greengriminal has quit [Quit: Leaving]
<FromGitter> <girng> @j8r yeah, I use it for my ram progress bar loader: Gif of WIP server manager system (https://i.gyazo.com/e6a5ce10170cf7ee0635b67102d58d0f.gif)
<FromGitter> <girng> i just threw in the top command there bcz why not lmfao
<FromGitter> <girng> crystal makes it super eZ
<FromGitter> <hmans> @girng Without forking?
<FromGitter> <hmans> @j8r Cool, I'll give that a whirl later.
<FromGitter> <girng> @hmans iuno.i just do this in a separate fiber: `temp_data = {sub_cmd: "GETSTATS", top_data: `top -b -n 1`}`
<FromGitter> <hmans> @girng That's cool.
<FromGitter> <j8r> I'm working on Disk usage and Network stats now
<FromGitter> <girng> but i also use the hardware repo, for memory ram n stuff cause it's easier.
<FromGitter> <girng> but just doing cmd stuff jujst bcz i find it fascinating
<FromGitter> <girng> to have all that data in a gui program. looks and feels really good.
<FromGitter> <hmans> Q: is it intentional that HTTP::Server won't let me control the `backlog` of the underlying TCPServer?
<FromGitter> <j8r> you run all as `nick`, lol
shalmezad has quit [Ping timeout: 248 seconds]
<Jenz> Would both look and feel better in a text interface imo
<FromGitter> <girng> @j8r :D
That_Guy_Anon has joined #crystal-lang
<FromGitter> <hmans> TcpServer defaults to SOMAXCONN in https://crystal-lang.org/api/0.23.1/TCPServer.html#new%28port%3AInt%2Cbacklog%3DSOMAXCONN%2Creuse_port%3Dfalse%29-class-method
<FromGitter> <girng> @jenz yeah. the richtextlabel some reason doesn't parse the blank spaces correctly. it would look better if it did. it would just like from a console
<Jenz> Sounds fixable though, girng
* Jenz :eyes:
<Jenz> Though I have no idea what richtextlabel is (in this case)
<FromGitter> <girng> @jenz, sorry meant RichTextLabel node from Godot engine. it lets you use bbCode stuff as text in a container. ⏎ ⏎ But yeah, this is how it's supposed tolook like (https://i.gyazo.com/41e39b620af77627f5e57721beef19ab.png), but for some reason when parsing it in the RTL container it doesn't save the spaces correctly
<FromGitter> <girng> kind of make top cmd look ugly and hard to read
<Jenz> Right, you're working on some kind of web-game written in crystal right?
<FromGitter> <girng> well, it's in the godot engine but can be exported to the web. but mostly working on back-end server stuff for it
<FromGitter> <j8r> you render in html, right?ù
<FromGitter> <girng> yeah it could. but im targeting towards desktop
<FromGitter> <girng> i think it exports to webassembly
<FromGitter> <girng> it also exports natively to linux
<FromGitter> <girng> which is a huge PLUS
<FromGitter> <girng> because linux devs love true linux games
That_Guy_Anon has quit [Remote host closed the connection]
rohitpaulk has quit [Ping timeout: 240 seconds]
Jenz has left #crystal-lang ["I'll be back"]
<FromGitter> <girng> :D
<FromGitter> <j8r> probaly a `.sub ' ', "&nbsp;"` can do the trick - not sure
<FromGitter> <girng> yah i'll try to replace some stuff. my end goal is to not run a cmd but jjust use hardware repo
<FromGitter> <girng> i really like that hardware repo tbh
<FromGitter> <j8r> thanks. soon you will be able to know the kbits down/up of your process
<FromGitter> <girng> hahaah
<FromGitter> <girng> that sounds epic
<FromGitter> <j8r> i probaly need to reorganize the PID struct: there is to much methods :-o
<FromGitter> <j8r> *generated by a macro
<FromGitter> <j8r> the harder part is the one that seems the "simpler": getting the disk usage
havenwood has joined #crystal-lang
havenwood has left #crystal-lang ["Textual IRC Client: www.textualapp.com"]
<RX14> I think you should use LibC directly
<RX14> that kind of info is completely platform specific
<FromGitter> <j8r> It isn't better to have it in the stdlib, like Go does?
<RX14> it's barely in go's stdlib
<FromGitter> <j8r> that's strange to have `LibC::Stat` and not `LibC::Statfs`
<FromGitter> <j8r> both are really platform specific
<RX14> but we only have libc::stat because it's used in the stdlib for File::Info
<FromGitter> <j8r> Maybe we can create a sort of `File::FsInfo`?
<FromGitter> <j8r> It's really useful to know the disk space, I've already done the bindings
<FromGitter> <j8r> I will send a PR and will see what will happen
<FromGitter> <masukomi> question about fibers and channels. doc's don't really make this clear. I want to spawn a bunch of things and then wait for them all to finish. I don't want to care how many there are or what order they finish in. What's the right approach here?
<FromGitter> <j8r> just spawn fibers so
<FromGitter> <j8r> channels are used to communicate, to send back informations
<FromGitter> <j8r> *messages
<FromGitter> <masukomi> so just have a bunch of spawn..do's (or put them in a loop) and then Fiber.yield and after the Fiber.yield everything has finished?
<oprypin> thats not what yield does
<FromGitter> <j8r> You can wait a message
<oprypin> if u have a constant number of jobs, use this macro. if not, just copy the idea
<FromGitter> <masukomi> @oprypin that snippet makes it look like i have to have a count of how many things {{ jobs.size }}.times { %channel.receive }
<FromGitter> <masukomi> looking at your thing @j8r
<oprypin> nothing to look at really
<oprypin> masukomi, well, don't you know how many things?
<oprypin> that's not even possible
<FromGitter> <masukomi> i do but it seems a somewhat silly requirement. i figured there must be some way to just say... hey lemme know when all the things you're managing are done
<oprypin> masukomi, what if you have a lib that spawns something you're unaware of
<oprypin> will you also wait for all its tasks? which may be infinite?
<oprypin> in fact, stdlib probably has infinite tasks as it is
<FromGitter> <masukomi> there's no way to know my fibers vs your fibers ?
<FromGitter> <girng> are there any benchmarks showing how many messages per second in a fiber TCP socket?
<oprypin> masukomi, your fibers are the ones you spawned ;)
<FromGitter> <girng> btw, what happens when that fiber can't handle those messages per second (are too high). what happens to the fiber, does it start to block the entire program, or does that fiber just start getting slow?
<FromGitter> <drujensen> @masukomi looks like you can name your fibers https://github.com/crystal-lang/crystal/blob/4f9ed8d03208dd0db33993c5a6fa6753bc1cf91e/src/fiber.cr#L26
<FromGitter> <drujensen> anyway to get a list of fibers and filter by name?
<FromGitter> <masukomi> i was starting to go down that road of exploration but don't see what the point is because i don't see how to tie spawn to a particular fiber
<FromGitter> <drujensen> aah
<FromGitter> <masukomi> and oprypin says yield doesn't make it wait for it to finish so even if i could i don't see how i could know that it was done.
<FromGitter> <masukomi> i really appreciate the help folks. i feel like i must be missing something obvious
<oprypin> i mean, you're missing the link that i posted
<oprypin> you tie channels, not fibers
<FromGitter> <masukomi> like "obviously there's a way to spawn a bunch of stuff that doesn't need to communicate to each other and then wait for it to finish" yes it CAN be done with channels (as in your link oprypin but that brings in overhead i don't need.
<FromGitter> <masukomi> sure it's minimal and it doesn't really matter in the long run but this really feels like it is something that *should* be there and we're just not seeing it for some reason
<FromGitter> <hmans> @masukomi Maybe I'm misunderstanding your question, but there are some examples for what you appear to want to do on https://crystal-lang.org/docs/guides/concurrency.html
<FromGitter> <hmans> ie., have your spawned fibers report back to a channel
<FromGitter> <masukomi> i didn't see any example in there that allowed you to wait and didn't require you to keep track of how many things were being spawned
<FromGitter> <hmans> Oh, I see
<FromGitter> <masukomi> i get how to do it with channels, but i don't need cross communication and it *feels* like a pretty common use case
<FromGitter> <masukomi> sorry. not trying to be obstinate
<oprypin> masukomi, if you dont want to keep track of how many things, you can also make N channels instead of 1 and wait for each.......
<oprypin> you may have a valid complaint that there isnt a standard wrapper to do this, but that's what it would do - count thing
<oprypin> s
<FromGitter> <masukomi> so in that case i'd do a bunch of channel.new's and then... loop over them until there were none left that returned a non truthy `receive?` ?
<FromGitter> <hmans> @masukomi Consider that this isn't really a Crystal specific problem. Go has something called WaitGroup to wrap around it
<FromGitter> <masukomi> i *think* i have enough info to move forwards. am i right about the `receive?` idea?
<FromGitter> <hmans> Assuming you have a module, class or other piece of code that is considered to be in control of spawning these fibers, it would need to do tracking of some sort. Doesn't need to be a channel. I suppose the units of work could also just decrement a number that was incremented when they were spawned, and the controlling fiber waits for the number to go back down to 0.
<FromGitter> <masukomi> mmm
<FromGitter> <hmans> And checking for non-blocking `receive?` might work, yeah, but it feels more complex than necessary
<FromGitter> <masukomi> *nods* cool. thank you all. if i come up with some good wrapper for this i'll make a PR
<FromGitter> <hmans> \o/
<FromGitter> <hmans> From Go's WaitGroup: "A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished. At the same time, Wait can be used to block until all goroutines have finished."
<FromGitter> <hmans> You can see there's some really basic stuff going on behind the scenes there.
<FromGitter> <j8r> How can I use `LibC.stat` directly? I tried some combinations of `LibC.stat("/home", result : LibC::Stat)` but still stuck :-/
<FromGitter> <j8r> also tried `uninitialized` and `Pointer.new`
<FromGitter> <masukomi> thanks @oprypin
<oprypin> WTF example.com is blocked on my ISP
<FromGitter> <hmans> It's a filthy site
<oprypin> masukomi, that combination of `ensure` and `uninitialized` was really unsafe so i updated the example
<oprypin> z64, that macro expects a constant number of items. also it's unsafe for the mentioned reason lol
<FromGitter> <j8r> @oprypin is it blocked DNS wise?
<oprypin> ERR_NAME_NOT_RESOLVED
<FromGitter> <girng> LOL
<FromGitter> <j8r> ISP's default DNS are shit, change it to https//dns.watch
<FromGitter> <j8r> free and uncensored
<FromGitter> <girng> can i do that on windows
<FromGitter> <j8r> yes, on most device you can change the DNS resolver
<FromGitter> <girng> interesting, i was watching this video (https://www.youtube.com/watch?v=kqnvrjgyEMc&t=140s) by linus tech tips he mentioned dns resolver
<FromGitter> <masukomi> example.com is a special case domain. it's literally reserved for examples
<FromGitter> <masukomi> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5aeb61fd5cf0b830045444dd]
<oprypin> yea dude i know, seems like my isp has busted DNS, just changed it
<FromGitter> <j8r> They also know on which sites you go :-/
rohitpaulk has joined #crystal-lang
<FromGitter> <hmans> Some news on how Ruby 3 is tackling threads et al: http://www.atdot.net/~ko1/activities/2018_RubyElixirConfTaiwan.pdf
<FromGitter> <girng> ok i set my dns gateway to 1.1.1.1 and it wouldn't let me load any sites
<FromGitter> <girng> so i went back to assign "automatically"
<FromGitter> <hmans> Haha, I like the slide that says "We need to design a library like OTP"
<FromGitter> <j8r> 1) 1.1.1?!
<FromGitter> <girng> yah, cloudflare's
<FromGitter> <girng> linustechtips video told me to
<FromGitter> <girng> lol i just following what they did though, not sure if they trolling
<FromGitter> <j8r> so cloudflare know every sites you visit, nice
<FromGitter> <girng> lol well it didn't even work so
<FromGitter> <girng> iuno
<FromGitter> <j8r> just https://dns.watch/ . Set IPv4 (and IPv6)
<FromGitter> <j8r> set at least two, if one is down there is another
<FromGitter> <girng> ok i'll try that
<oprypin> girng, DNS server and gateway is entirely different
<FromGitter> <girng> this is what i changed: https://i.gyazo.com/fbd462149e92a0c2da532d61e9ebb926.png
<FromGitter> <girng> if i use a custom dns address server, no sites will load.
<FromGitter> <girng> i tried cloudflare, and j8r's dns.watch
<FromGitter> <girng> in any event im done wasting my time on this premature optmization bullshit
<FromGitter> <j8r> Don't know how in Windows
<FromGitter> <girng> my sites load just fine
<FromGitter> <j8r> Changing DNS is primilarly for privacy
<FromGitter> <j8r> not really perf
<FromGitter> <hmans> I'm adding `hardware` to crankypants...
<FromGitter> <hmans> @j8r memory.percent seems to always claim a usage of 20% -- work in progress?
<FromGitter> <hmans> (memory.used is 836064, which seems realistic)
<FromGitter> <bararchy> @hmans what distro?
<FromGitter> <hmans> @bararchy This is currently inside a Docker VM running on a Mac. The Container is using the Crystal image. I'm assuming the 20% is Docker related?
<FromGitter> <hmans> Let me run it outside of Docker...
<FromGitter> <hmans> (Will it even work on something that's not Linux?)
<FromGitter> <hmans> (Well, I just found out :b)
rohitpaulk has quit [Ping timeout: 264 seconds]
<FromGitter> <j8r> For now it only works in Linux. Maybe some things in BSD variants, but I doubt...
<FromGitter> <j8r> Use another tool to check the CPU usage if it match or not, like `top`
<FromGitter> <j8r> sorry you said memory, check with `free -g`
<FromGitter> <hmans> I will dig deeper tomorrow. Bed time for me.
<FromGitter> <girng> gn
<FromGitter> <hmans> Talk to you guys tomorrow o7
<FromGitter> <j8r> see you!
duane has quit [Ping timeout: 240 seconds]
<crystal-gh> [crystal] j8r opened pull request #6056: Add bindings for LibC::Statfs (master...statfs) https://git.io/vpaqf
duane has joined #crystal-lang
sz0 has joined #crystal-lang
<FromGitter> <girng> is opyrin on
<FromGitter> <girng> guess not. anyway, anyone can help
<FromGitter> <girng> damnit, the ips are supposed to be different. They are different servers
<FromGitter> <fridgerator> communication is via websockets?
<FromGitter> <girng> via tcp stream
<FromGitter> <girng> they are connected though. i make a connection to them through tcp to let the master server know
<FromGitter> <fridgerator> and message are sent and retrieved?
<FromGitter> <girng> yeah. but only for important stuff. like for example if someone finds and items and loots it
<FromGitter> <girng> i need it to be saved on the master items database
<FromGitter> <fridgerator> well I can only speak to how websocket servers usually work, all messages are posted to something like Redis
<FromGitter> <girng> do i send a message to notify the master server to run the db.query. or do i just connect to the database from the game instance server
<FromGitter> <fridgerator> each instance of the server posts all messages to Redis, they also each listen to Redis for new messages
<FromGitter> <girng> remotely db connection, and then do it. or do i send a message internally tcp to master server user_id, itemid that they looted, then update the db
<FromGitter> <fridgerator> so a Redis service is kind of used like a "master"
<FromGitter> <girng> yeah i did that with nodejs
<FromGitter> <girng> redis pub sub stuff
<FromGitter> <fridgerator> yeah
<FromGitter> <girng> so i guess the game instance server will notify the master. then the master runs the database query. that's how i would do it with a redis pubsub. but i mean, i could open up my mysql db connection remotely. and have the game instance server connect to it. then just call the database query on that game instance server. im not sure
<FromGitter> <girng> there's so many freaking ways to do it
duane has quit [Ping timeout: 260 seconds]
<FromGitter> <fridgerator> Well, the database is going to be a bottleneck with lots of users
<FromGitter> <fridgerator> I wouldn't write / read from a database on every action
<FromGitter> <girng> oh yea for sure. i mean like if a player loots an item though
<FromGitter> <girng> it needs to be saved to their inventory instantly
<FromGitter> <girng> i just don't know if that save query should be just called on the game instance server, or on the master server.
<FromGitter> <girng> if on game instance server, it will need to create a connection to the main database. im not sure if that's safe
<FromGitter> <girng> main mysql port will be open
<FromGitter> <girng> 3306
hightower2 has joined #crystal-lang
<hightower2> Hey, I have kind of an abstract question :) I know I can make an abstract class or define things within a module as abstract, But is there a way to check that I am only invoking the methods on an object which are defined in that abstract interface?
Nathanaelle has quit [Ping timeout: 240 seconds]
<FromGitter> <j8r> not sure to understan @hightower2
<FromGitter> <j8r> You define abstracts, and ther create a class that inherit of the abstracted class
<crystal-gh> [crystal] RX14 closed pull request #6056: Add bindings for LibC::Statfs (master...statfs) https://git.io/vpaqf