<FromGitter>
<Blacksmoke16> do you just read the data in `/dev/ttyUSB0`?
<FromGitter>
<Blacksmoke16> could use `gets_to_end`which would read the data at once as a string
<FromGitter>
<asterite> when `gets` doesn't have anything to read and it's not the end, it blocks and another fiber executes
<FromGitter>
<asterite> I tried it on my machine with a regular file (not a socket) and it works fine, so maybe the problem is related to the file being a socket
<FromGitter>
<asterite> but I don't have `/dev/ttyUSB0` on my machine so I can't try it
<FromGitter>
<omidathari> That is exactly what i expected
<FromGitter>
<omidathari> @asterite I've gotten that to work perfectly for udp/tcp sockets, but for some reason with this serial fd calling `gets` seems to interfere with stdin.
<FromGitter>
<Blacksmoke16> gets waits for input from STDIN
alexherbo25 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 246 seconds]
<FromGitter>
<omidathari> @Blacksmoke16 exactly. My problem is that `gets` blocks as expected and the fiber runs. But when `sf1.gets` is called it hangs instead of blocking and allowing input from stdin to be picked up by gets.
<FromGitter>
<Blacksmoke16> yea sadly we're at the extend of my knowledge on this area :/
<FromGitter>
<omidathari> @asterite It seems like calling gets on a TTY file descriptor hangs instead of blocks. We've already tried breaking these out into different files instead of fibers and letting the OS handle concurrency. Not a great solution but it works. Do you have any suggestion?
prettyrobots has joined #crystal-lang
prettyrobots is now known as sympatico
<FromGitter>
<tenebrousedge> is there any way to test this on Unix without having the hardware?
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
<FromGitter>
<straight-shoota> No, `case` is essentially just a different way of writing a series of `if ... elsif`. So you need to use regular control flow mechanics.
<FromGitter>
<Blacksmoke16> works fine if you remove the nested hash
<jokke>
any obvious reason why HTTP::Server doesn't support listening on file descriptors?
<FromGitter>
<mwlang> @asterite and @Blacksmoke16 Thanks for the pointers on using select. I had to spend some time to get to understand that one. I don't think select is my problem, though. I reduced the code further to just running one Listener and I still had an issue with breaking out of the spawned run loop, this time when the websocket received an unexpected message.
<FromGitter>
<Blacksmoke16> np, what does it do? :p
<jokke>
i'd like to experiment with socket activated systemd services
<FromGitter>
<mwlang> I have solved the unexpected message issue by attempting to parse JSON with rescue block.
<FromGitter>
<mwlang> what does select do? It lets you listen for more than one channel update at once.
<FromGitter>
<yxhuvud> listening on socket files would make sense. listening on other type of files perhaps not so.
<FromGitter>
<Blacksmoke16> hmm, gotcha
<FromGitter>
<mwlang> @Blacksmoke16 that play looks like a recursive / circular reference sort of issue.
<FromGitter>
<straight-shoota> jokke, HTTP::Server supports UNIX sockets and for regular use cases you won't need more anyway
<jokke>
i see
<FromGitter>
<Blacksmoke16> yea but its still a valid type no?
<FromGitter>
<Blacksmoke16> just would allow the hash to have a hash as a property and so on
<FromGitter>
<mwlang> far as I know!
<FromGitter>
<mwlang> can you add to a union after it's been declared?
<FromGitter>
<straight-shoota> If you want to listen on an arbitrary file descriptor, you could just implement a `Socket::Server` for this and bind it to the server. Maybe `http_server.bind UNIXServer.new(fd: file_descriptor)` would already be enough.
<FromGitter>
<straight-shoota> jokke, Alternatively, if you only need to serve a single connection anyway, you could use `HTTP::RequestProcessor` directly with a `IO::Filedescriptor`
<FromGitter>
<mwlang> There we go. That's what I'd do anyway. Reads better.
<jokke>
hm yeah idk
<FromGitter>
<Blacksmoke16> ehh thats what im doing now but id rather do like `@context : LogContext := LogContext.new`
<FromGitter>
<Blacksmoke16> but meh
<jokke>
straight-shoota: then stuff like Connection: keepalive wouldn't work i suppose
<FromGitter>
<straight-shoota> Why not?
<jokke>
would HTTP::RequestProcessor handle multiple requests?
<jokke>
i'll just give it a try :)
livcd has quit [Quit: Lost terminal]
livcd has joined #crystal-lang
<jokke>
sweet
<jokke>
it works like a charm
livcd has quit [Read error: Connection reset by peer]
<FromGitter>
<pynixwang> sleep main Fiber other fibers execute more?
<FromGitter>
<Blacksmoke16> doing a `sleep` in main fiber would cause main fiber to block, thus allowing other fibers to execute
<FromGitter>
<bararchy> Fiber.yield :)
<FromGitter>
<pynixwang> I want main Fiber to be a watch dog
<FromGitter>
<pynixwang> sleep 100 second then check other fibers
<FromGitter>
<pynixwang> are there any general fiber manager?
<FromGitter>
<mwlang> Is this a general "Exception" error? I want to capture and handle gracefully, but I'm not sure if the exception class is "Exception" or it is... ā ā ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5cdec0c3509b1035c7647661]
<FromGitter>
<Blacksmoke16> is `Errno`
<FromGitter>
<mwlang> So what's in parentheses is the class name of the exception?
<FromGitter>
<Blacksmoke16> it inherits from `Exception`
<FromGitter>
<Blacksmoke16> ye, would be an exception thrown from the c lib
<FromGitter>
<mwlang> So how do I make use of the constants defined in the Errno module? For example, To handle specifically a peer reset in Ruby, it would be ```rescue Errno::ECONNRESET => e```
<FromGitter>
<Blacksmoke16> maybe like `rescue Errno` then a case based on the response?
<FromGitter>
<mwlang> hmmm...and just re-raise the error in a case's else clause?
<FromGitter>
<Blacksmoke16> assuming you wanted to catch a specific error, could catch the ones you want then handle rest in the else block
<FromGitter>
<mwlang> ok, that's what I thought you were suggesting.
<FromGitter>
<mwlang> oh, boy...now I gotta figure out how to re-launch a spawned run... ie. ```spawn { @ws.run }```
<FromGitter>
<Blacksmoke16> :shrug:
tdc has joined #crystal-lang
<FromGitter>
<mwlang> I cannot quite figure out how to detect when a spawned fiber goes away so that another loop can detect this and also exit it's fiber.
<FromGitter>
<mwlang> specifically where I have "exit" in the rescue block...I want to stop the fiber and simultaneously somehow signal to the while ```line = channel.receive?``` that this fiber is no longer running
<FromGitter>
<tenebrousedge> does `spawn` have a return value? the `Fiber` class does have `dead?` and `running?`
<FromGitter>
<jgaskins> Also, hi @mwlang! š :-D
<FromGitter>
<mwlang> Hi, @jgaskins :-D
<FromGitter>
<mwlang> ok, so I iterated this but it seems so wrong to utilize the channel itself to communicate a dead fiber: https://play.crystal-lang.org/#/r/6xlr
<FromGitter>
<mwlang> So, are you messing around with crystal these days, @jgaskins?
<FromGitter>
<z64> @mwlang yes that is the way to handle this - using channels to communicate, and just letting the fiber exit and be collected when its done ā ā you can utilize some types to make this more useful https://play.crystal-lang.org/#/r/6xlw
<FromGitter>
<mwlang> @z64 thanks for that! I did not even think about types other than Strings, so yes, this makes it feel a lot cleaner in implementation
<FromGitter>
<z64> yw š
<FromGitter>
<jgaskins> @mwlang Yeah, I've been building a few things with it. :-) Trying to work a few microservices to use it at work, but I've also been working on a few other projects, like a Neo4j driver and a port of Phoenix LiveView.
<FromGitter>
<mwlang> Ah, your love of graph databases. :-D Sounds like fun with the Neo4j driver. As for micro-services, that's where I'm at as well -- replacing a few slow running Ruby data collectors with Crystal equivalents.
<FromGitter>
<tenebrousedge> @jgaskins what do you love about graph databases/neo4j ?
<FromGitter>
<mwlang> I think I'll go ahead and start my first open source crystal contribution...writing binance api library wrappers (https://github.com/binance-exchange/binance-official-api-docs) I've just been doing this in raw form as I learn Crystal, but writing a shard can help me learn Crystal a bit more formally, I think.
<FromGitter>
<dscottboggs_gitlab> I feel like I'm missing something obvious here... https://carc.in/#/r/6xm0
<FromGitter>
<Blacksmoke16> š¬
<FromGitter>
<dscottboggs_gitlab> what?
<FromGitter>
<Blacksmoke16> i have no idea whats going on :S
<FromGitter>
<dscottboggs_gitlab> lol oh I thought it was really obvious and you knew right away
<FromGitter>
<dscottboggs_gitlab> but that sort of response was why I thought the answer "use `OpenSSL::Cipher`" was an inadequate answer to the question "how do I encrypt something"
<FromGitter>
<dscottboggs_gitlab> like there should be a shard that lets you do `Object#encrypt` and `Object.decrypt`
<FromGitter>
<jgaskins> @tenebrousedge I love SQL but it's not super expressive and it requires you to think in terms of relational algebra. This is awesome in a lot of ways, but as an app developer moving back and forth between treating my objects as domain objects vs storage model is a total brain melt.
<FromGitter>
<jgaskins> I think Neo4j's query language Cypher is even more expressive than any Ruby or Crystal DSL I would write around it. There's a lot of great benefits to persisting the objects in a similar structure to how you're using them in the application.
<FromGitter>
<tenebrousedge> @jgaskins my last project was based on neo4j, but the requirements were vague and trivial, so I didn't get very deep into it. Do you have a project you'd like to show off?
<FromGitter>
<dscottboggs_gitlab> @Blacksmoke16 it was just the conversion between Base64 that was causing the trouble I think, but I've got something else to do right now, I'll let you know when I get it working
<FromGitter>
<Blacksmoke16> š
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
DTZUZO has quit [Read error: Connection reset by peer]
sz0 has quit [Quit: Connection closed for inactivity]
<FromGitter>
<Blacksmoke16> hmm, gotcha
<FromGitter>
<vladfaust> I need a little help. I'm writing to a socket, and server (bare socket server) `gets`. But `while temp = gets` is stuck unless the socket (not the server) is closed
<FromGitter>
<vladfaust> I don't want to close the client socket, I want to reuse it instead
<FromGitter>
<vladfaust> But `while temp = client.gets` just freezes
<FromGitter>
<vladfaust> Well, socket's IO doesn't have end unless it's closed, I see
<FromGitter>
<vladfaust> Nevermind, I've got this š
alexherbo250 has joined #crystal-lang
alexherbo25 has quit [Ping timeout: 244 seconds]
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
<FromGitter>
<jwoertink> glad we could be of some help! š„
laaron- has joined #crystal-lang
laaron has quit [Remote host closed the connection]
<FromGitter>
<dscottboggs_gitlab> I agree it would be kinda convenient if we could have a defined fixture for a `describe` block but it has not been implemented yet