greengriminal has quit [Quit: This computer has gone to sleep]
non-aristotelian has quit [Quit: non-aristotelian]
non-aristotelian has joined #crystal-lang
non-aristotelian has quit [Ping timeout: 244 seconds]
akaiiro has quit [Ping timeout: 272 seconds]
non-aristotelian has joined #crystal-lang
non-aristotelian has quit [Ping timeout: 240 seconds]
akaiiro has joined #crystal-lang
akaiiro has quit [Ping timeout: 272 seconds]
akaiiro has joined #crystal-lang
return0e_ has joined #crystal-lang
return0e has quit [Read error: Connection reset by peer]
rohitpaulk has joined #crystal-lang
akaiiro has quit [Ping timeout: 252 seconds]
akaiiro has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 245 seconds]
rohitpaulk has joined #crystal-lang
_whitelogger has joined #crystal-lang
akaiiro has quit [Remote host closed the connection]
t0nyandre has joined #crystal-lang
t0nyandre has quit [Quit: WeeChat 2.3]
Raimondii has joined #crystal-lang
ashirase has quit [Ping timeout: 244 seconds]
Raimondi has quit [Ping timeout: 246 seconds]
Raimondii is now known as Raimondi
ashirase has joined #crystal-lang
druonysus has quit [Read error: Connection reset by peer]
ua_ has quit [Ping timeout: 252 seconds]
rohitpaulk has quit [Ping timeout: 240 seconds]
non-aristotelian has joined #crystal-lang
non-aristotelian has quit [Ping timeout: 252 seconds]
ua has joined #crystal-lang
rohitpaulk has joined #crystal-lang
t0nyandre has joined #crystal-lang
ua has quit [Ping timeout: 252 seconds]
ua has joined #crystal-lang
BigForceGun has joined #crystal-lang
BigForceGun has quit [Ping timeout: 240 seconds]
tankf33der has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 246 seconds]
rohitpaulk has joined #crystal-lang
teardown has joined #crystal-lang
tilpner has quit [Remote host closed the connection]
rohitpaulk has quit [Ping timeout: 272 seconds]
tilpner has joined #crystal-lang
rohitpaulk has joined #crystal-lang
moei has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 244 seconds]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 268 seconds]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 252 seconds]
akaiiro has joined #crystal-lang
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 268 seconds]
ashirase has quit [Ping timeout: 252 seconds]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 246 seconds]
non-aristotelian has joined #crystal-lang
rohitpaulk has joined #crystal-lang
t0nyandre has quit [Ping timeout: 272 seconds]
greengriminal has joined #crystal-lang
akaiiro has quit [Ping timeout: 268 seconds]
FromGitter has joined #crystal-lang
<FromGitter>
<fridgerator> I just noticed the release
<FromGitter>
<fridgerator> 🎉
<FromGitter>
<fusillicode_twitter> Damn I'm battling with nested transactions...
<FromGitter>
<fusillicode_twitter> ...again...
<FromGitter>
<fusillicode_twitter> :(
<FromGitter>
<fusillicode_twitter> I just want to perform multiple transactional insert and ignore unique constraints :'(
<FromGitter>
<fusillicode_twitter> All this inside another transaction
<FromGitter>
<bew> @vladfaust using `read_file` for this wouldn't work, because the file path won't pass through require's file resolution system
rohitpaulk has quit [Ping timeout: 252 seconds]
<FromGitter>
<jemc> I'm new to Crystal, and a little confused by IO at the moment - how do I do a blocking `gets` from `STDIN` (or, if I can't do a blocking `gets`, I'd settle for any other blocking read operation)? I have a program where I `spawn` a fiber to read in a loop and send deserialized stuff out through a `Channel`, and I thought I was doing a blocking read in my loop, but it turns out I'm just busywaiting...
<FromGitter>
<jemc> I've tried calling `IO::FileDescriptor#blocking=` with `true`, but it doesn't seem to have any effect? (also, I'd strongly prefer to just call a "blocking read" method rather than setting state on the file descriptor if possible...
<FromGitter>
<jemc> If I can't do a blocking read, `IO.select` would be cool, but it seems like that's been removed? (https://github.com/crystal-lang/crystal/issues/3169) ⏎ ⏎ I know that the literal syscall `select` isn't appropriate in a libuv-evented context, but it would still be possible to implement `IO.select` with libuv (I once did this for Ruby, actually: https://github.com/jemc/rub
<FromGitter>
<asterite> @kinxer exactly, nothing is really private
<FromGitter>
<asterite> @jemc Hi! :-) . Why do you need a blocking read?
<FromGitter>
<jemc> I wouldn't say I definitely need a blocking read if there's a more idiomatic way to do what I want to do
akaiiro has joined #crystal-lang
<FromGitter>
<jemc> so I'm trying to create an abstraction that acts like `Channel#receive` does (blocking the current fiber until the next object is available) - internally it reads from an `IO` in a loop (usually `STDIN`, but sometimes other `IO` kinds for testing), deserializes some messages from it, and pushes those out for the `receive`-like method
<FromGitter>
<jemc> as I mentioned above, I did this with a `spawn` that does `IO#gets` in a loop and parses the results
<oprypin>
jemc, the main problem may be that its not a good idea to do input in non-main fiber
<FromGitter>
<jemc> but without blocking reads, this just is a busywait that overuses the CPU when there is no data available
<FromGitter>
<asterite> but if there's no data the CPU does nothing, right?
<FromGitter>
<asterite> also, I just tried `STDIN.blocking = true` and it seems to work (but I wouldn't recommend it because standard file descriptors in the console are kind of shared and it's a mess)
<FromGitter>
<asterite> so with `blocking = true` you don't get to see those `puts 1`, but with `blocking = false` you do
<FromGitter>
<jemc> so I may be miscommunicating here - just to clarify, when I say "blocking", I mean "yield the current fiber until input is ready to read"
<FromGitter>
<asterite> oh, in my mind that's non-blocking
<FromGitter>
<jemc> > but I wouldn't recommend it because standard file descriptors in the console are kind of shared and it's a mess ⏎ ⏎ Yeah, as I mentioned above, I'd love to avoid mutating state on the file descriptor
<FromGitter>
<jemc> so when I say "non-blocking" behaviour I mean "returns `nil` immediately when there is no data, without blocking the fiber"
<FromGitter>
<jemc> but I can use whatever terms make the most sense here
<FromGitter>
<asterite> Oooooh... I see
<FromGitter>
<jemc> yeah, so my desired behaviour is to read from STDIN like it was a `Channel.receive`, yielding the fiber until data is available to read
<oprypin>
but that's what happens by default
<FromGitter>
<asterite> well, by default you go to another fiber. He wants to stay in the fiber and know that there's nothing immediately available
<FromGitter>
<jemc> @asterite - no, that's not what I want, sorry
<FromGitter>
<jemc> I'm still not being clear I guess
<FromGitter>
<jemc> oprypin: for what method? `IO#gets` or something else?
<oprypin>
gets
<FromGitter>
<asterite> there's nothing like that but it shouldn't be hard to implement
<FromGitter>
<jemc> let me try to come up with a minimal example and see how it compares to the behaviour I see in my actual code
<oprypin>
yes
<FromGitter>
<jemc> maybe something else strange is going on to make me busywait
<oprypin>
it seems to me that something is wrong with socket flush_on_newline again
<FromGitter>
<jemc> what I get from that program is that it prints whatever it got in `STDIN`, then it prints `nil` forever in a busywait loop
<oprypin>
oh? that's not what i get
<FromGitter>
<jemc> what I want is a for that program to print data when it becomes available, but otherwise just wait for the next data to come in
<oprypin>
and that's what your program does for me
<FromGitter>
<jemc> oprpyin: interesting...
<FromGitter>
<jemc> are you feeding it anything into `STDIN` when you run it? I am in my test
<oprypin>
jemc, i just run the program
<FromGitter>
<jemc> I'll try feeding it nothing...
<oprypin>
jemc, so you mean you pipe something into it?
<oprypin>
shouldve started with that
<FromGitter>
<jemc> yeah, I was piping a JSONRPC message into it in my test
<FromGitter>
<asterite> how do you do that in, say, Ruby?
<oprypin>
echo a | crystal test.cr
<FromGitter>
<jemc> when I pipe nothing into it, it waits patiently as desired
<oprypin>
i see - you get nil forever here
<oprypin>
but it just means that the file descriptor is closed, and it's expected behavior
<FromGitter>
<asterite> I ask because Ruby behaves in the same way :-)
<FromGitter>
<ukd1> I might be being dumb, but I can't figure out how to use JSON mapping with variable key names? i.e. {unknown_1: {...}, unknown_2: {...}}
<FromGitter>
<ukd1> if anyone has an idea / sample <3
<oprypin>
ok this may not be entirely true
<FromGitter>
<jemc> @asterite - In Ruby, my go-to is `IO#readpartial`
<FromGitter>
<jemc> (I use `IO#readpartial` or `IO.select` when I want blocking I/O in Ruby, but neither is present in Crystal)
<FromGitter>
<jemc> (so I'm just trying to get something similar, even if it's not the methods I'm used to)
<oprypin>
people, i am seriously disturbed by sockets flushing in crystal 0.26.1
<FromGitter>
<asterite> I think you'll have to structure the program in a different way. There's no such thing in Go (neither readpartial nor select) and Crystal basically follows the Go model for IO
<oprypin>
the socket flushes only when anything else happens in the application
<FromGitter>
<jemc> @asterite - that's super weird to me that neither Go nor Crystal has a way to make I/O act like `Channel#receive` when that's like the cornerstone of the concurrency patterns?
<oprypin>
the typical effect on this is that I see your messages from Gitter only when someone else writes the next message, either on Gitter or on IRC
<oprypin>
asterite, the point here is that it's possible to make it so `gets` instantly returns nil in a loop and does not block
<FromGitter>
<asterite> `Channel#receive` kind of works the same way: if there's nothing there it will block (yield to another fiber) and when there's data it will resume that fiber
<FromGitter>
<jemc> @asterite - that's exactly how I want IO to act
<FromGitter>
<jemc> I guess I need to add a check for if the FD is closed, to break the loop?
<FromGitter>
<asterite> if `gets` returns `nil` it means the FD is closed
<oprypin>
`echo a | crystal eval 'loop { p STDIN.gets }'` illustrates this
<oprypin>
yeah dont loop on nil
<oprypin>
BUT if I just run `crystal eval 'loop { p STDIN.gets }'` then i press Ctrl+D it can return nil once but then i can ceep typing and it will be non-nil
<FromGitter>
<asterite> oprypin: yeah, that's strange. On the other hand I see the same behavior in Ruby, so it might have something to do with the console
greengriminal has quit [Quit: This computer has gone to sleep]
<oprypin>
maybe
<FromGitter>
<jemc> oprypin: but I can just check `IO#closed?` instead of basing my `break` on the return value, and I'll be golden, right?
<FromGitter>
<jemc> :)
<FromGitter>
<jemc> looks like `IO#closed?` returns `false` for me
<FromGitter>
<jemc> when I run `echo a | crystal eval 'loop { p STDIN.gets; p STDIN.closed? }'`
<FromGitter>
<asterite> Right... maybe a think with STDIN. On the other hand Ruby prints the same :-S
<FromGitter>
<asterite> but why can't you use the return value from `gets`? If it's `nil` it means there's no more data
<FromGitter>
<jemc> oprypin just mentioned an issue with that above
<FromGitter>
<jemc> > *<oprypin>* BUT if I just run `crystal eval 'loop { p STDIN.gets }'` then i press Ctrl+D it can return nil once but then i can ceep typing and it will be non-nil
FromGitter has quit [Remote host closed the connection]
<oprypin>
`<<` is implemented with obj.to_s(self) but obj.to_s(io) is implemented with `io << stuff`
FromGitter has quit [Remote host closed the connection]
FromGitter has joined #crystal-lang
<FromGitter>
<oprypin> added `.flush` in addition to `flush_on_newline`, hopefully this will work
<oprypin>
and it did :/
<oprypin>
`flush_on_newline` is broken on TCPSocket and while trying to understand why, i realized that i have no idea how `TCPSocket#<<` even works, it's supposed to be an endless recursion
<oprypin>
is there a good way to make a repro with sockets locally?
<oprypin>
ah i guess just make a server locally
<oprypin>
nvm, it's probably specific to SSL socket
jemc has joined #crystal-lang
t0nyandre has joined #crystal-lang
t0nyandre has quit [Ping timeout: 268 seconds]
<oprypin>
yes, made a repro!!
jemc has quit [Ping timeout: 244 seconds]
<oprypin>
but it fails on an old version of crystal -_- `BIO routines:bio_read_intern:unsupported method (OpenSSL::SSL::Error)` - what am i supposed to do with this
<FromGitter>
<vladfaust> @bew, ⏎ ⏎ > @vladfaust using `read_file` for this won't work, because the file path won't pass through require's file resolution system ⏎ ⏎ I think `__DIR__/lib` will work in this case [https://gitter.im/crystal-lang/crystal?at=5bdcde54995818347b9441e4]
<FromGitter>
<vladfaust> However, `require?` is useful IMO
<FromGitter>
<bajro17> is crystal 0.27 out?
<FromGitter>
<Blacksmoke16> yes, updated via apt hour or so ago