<FromGitter>
<Blacksmoke16> .each just iterates over each key/value in the hash, while select returns a new hash consisting of entries for which the block which is true
<FromGitter>
<Blacksmoke16> @girng
<FromGitter>
<girng> @Blacksmoke16 @asterite thanks. i'll use min_by much cleaner
<FromGitter>
<Blacksmoke16> indeed
<FromGitter>
<girng> @Blacksmoke16 understood. so only certain methods can have a return value (.select compared to .each). using .each with a return value makes no sense then?
<FromGitter>
<Blacksmoke16> im pretty sure bew explained to you that .each returns nil
<FromGitter>
<Blacksmoke16> a while back
<FromGitter>
<girng> yea, i get the block and method part confused
<FromGitter>
<bew> each without a block returns an iterator
<FromGitter>
<girng> ooo
<FromGitter>
<girng> well, i want to use select now
<FromGitter>
<girng> instead of each lol
<FromGitter>
<girng> bcz if select, i can return something if iwant to
<FromGitter>
<girng> more fair imo
<FromGitter>
<bew> `@girng.brain.unlock`
<FromGitter>
<Blacksmoke16> xD
<FromGitter>
<Blacksmoke16> what you trying to do exactly?
<FromGitter>
<bew> @girng it depends on the usecase! Note that `Enumerable#select` returns an Array, but `Iterator#select` returns an `Iterator`
<FromGitter>
<girng> yeah. true. just saying i fi would ahve used .select instead of .each when i was trying to figure it out i would have found the solution already lol
<FromGitter>
<girng> cuase it would have returned it to `find_first`
<FromGitter>
<Blacksmoke16> mhm
<FromGitter>
<Blacksmoke16> you could have got your .each to work by doing like
<FromGitter>
<girng> in any event. what i'm doing is a https://en.wikipedia.org/wiki/Round-robin_scheduling of the game servers which have the lowest load. when a player goes to create a game, the master servers will use the `min_by` method and get the first server that has the lowest amount of player. and that will be the next server the next player will use for their game instance
<FromGitter>
<Blacksmoke16> and could have used `.min` vs sorting the array and selecting first value
<FromGitter>
<girng> it's really nice anyways so i appreciate the help i think it'll work good.
<FromGitter>
<Blacksmoke16> or `temp_array.first`
<FromGitter>
<Blacksmoke16> bit more readable
<FromGitter>
<Blacksmoke16> but imo id prefer readability over speed (at least in regards to using .select vs .each)
<FromGitter>
<girng> that's interesting the map and min
<FromGitter>
<girng> much more cleaner than my temp_array = [] of Int32 and temp_array << rofl
<FromGitter>
<Blacksmoke16> mhm ;)
<FromGitter>
<girng> just a simple 1 liner with &.
<FromGitter>
<girng> nice one
<FromGitter>
<girng> i still can't get that &. stuff engrained in my head lol
<FromGitter>
<girng> i always resort to writing out the blocks 😢
<FromGitter>
<Blacksmoke16> you'll get there
<FromGitter>
<girng> i can't help it xD
<FromGitter>
<girng> ` ⏎ p game_servers.values.map &.online_count`especially cuz this is valid
<FromGitter>
<Blacksmoke16> im not a super big fan of no ()
<FromGitter>
<girng> parenthesis are not required. but if it's used with parenethesis, it's easier to rad actually
<FromGitter>
<girng> for me
<FromGitter>
<Blacksmoke16> yea
<FromGitter>
<girng> if using the &. not globally
<FromGitter>
<girng> some methods i don't ike using parenthesis hahaha
<FromGitter>
<girng> but when &. is involved, feels like parenthesis are needed :O
<FromGitter>
<girng> ``` spawn do ⏎ loop do ⏎ sleep 0.067.seconds ⏎ end ⏎ end``` ⏎ ⏎ Game loop time. each fiber (game instance) gonna be 15hz tick rate 1/15 = 0.067. 6players per fiber. each cheap $5.00 vps will prob house 100 players. which will be around 16 games. that'sgoing to be a total of 250 iteration per second. crystal should handle that quite well right or is too much?
<FromGitter>
<bew> of yeah, that works only if the type is Indexable
<FromGitter>
<Blacksmoke16> mhm
<FromGitter>
<bew> so even doing [1] wouldn't work
<FromGitter>
<Blacksmoke16> really the issue i just came across was like consistency, like can do `.first` on some things but then have to do [0] on others or char_at on others
<FromGitter>
<bew> for consistency let's keep only first, because otherwise we'll never finish ^^
<FromGitter>
<bew> and yes
<FromGitter>
<bew> the way to access to element can different for different types
<FromGitter>
<Blacksmoke16> not a major issue just a bit annoying sometimes
Yxhuvud has quit [Quit: No Ping reply in 180 seconds.]
Yxhuvud has joined #crystal-lang
Yxhuvud has quit [Quit: No Ping reply in 180 seconds.]
Yxhuvud has joined #crystal-lang
Yxhuvud has quit [Client Quit]
Yxhuvud has joined #crystal-lang
<FromGitter>
<bew> g++ doesn't want my special crystal-like C++ syntax, that's weird 😛 it's hard to write C++ now that my mind is in crystal mode...
Yxhuvud has quit [Quit: No Ping reply in 180 seconds.]
Yxhuvud has joined #crystal-lang
<FromGitter>
<girng> WOW, this redis shard is freaking amazing
<FromGitter>
<girng> synchronous redis commands.. = im in heaven
<FromGitter>
<girng> crystal docs system needs their search fixed
<FromGitter>
<girng> i go bed. work on redis stuff tomorrow too! very excited, loving the redis shard. ttyl all gn thanks for support
That_Guy_Anon has joined #crystal-lang
notdaniel has quit [Remote host closed the connection]
notdaniel has joined #crystal-lang
<FromGitter>
<bararchy> Does Crystal has a shard with logrotate support ?
hightower2 has quit [Ping timeout: 248 seconds]
<oprypin>
bararchy, why do you care about that?
<FromGitter>
<bararchy> well, I want to configure a log rotation system to my crystal logfile, I can use logrotate, but I know that Ruby has an option to decide max log file size and how many versions back to save
<oprypin>
bararchy, i dont know if you've heard but there's this thing called systemd
<FromGitter>
<bararchy> Is there? never heard of it ;)
<oprypin>
i have this irc bot running for years just printing every message into stdout and systemd stores the logs "somehow", i dont care how
<FromGitter>
<bararchy> so just log to stdout while systemd send it;s to journal
<FromGitter>
<bararchy> hm...
<FromGitter>
<bararchy> well, it's a good idea to be honset
<FromGitter>
<bararchy> do you know how long back is this log handled
<FromGitter>
<bararchy> nah, I'll just go read about it
<oprypin>
however you configure it, for me seems like for ever
<FromGitter>
<bararchy> thanks oprypin, sometime you sarcasm is helpful ;)
<FromGitter>
<j8r> for you systemd problem of logging to journal?
<oprypin>
there is no problem
<FromGitter>
<j8r> oh ok, I didn't follow everything.
<FromGitter>
<j8r> I'v seen ⏎ ⏎ > i have this irc bot running for years just printing every message into stdout and systemd stores the logs "somehow", i dont care how
andersh has quit []
andersh has joined #crystal-lang
That_Guy_Anon has quit [Remote host closed the connection]
jokke has quit [Ping timeout: 260 seconds]
<FromGitter>
<bararchy> If any of you guys is interested in a small and generalized example of Q-Learning in Crystal @ArtLinkov just added a nice example at https://github.com/ArtLinkov/qlearning
<FromGitter>
<bararchy> it's a small fun game that teach an agent to play a map with reward and punishment
<FromGitter>
<ArtLinkov> Thanks @bararchy :)
<FromGitter>
<bew> do you have a simple description of what qlearning is?
<FromGitter>
<j8r> Just played, like it - but what's the goal of the game?
rohitpaulk has quit [Ping timeout: 260 seconds]
<FromGitter>
<ArtLinkov> Q-learning is a method for an agent to "learn" the environment by exploration, without knowing the layout in advance. So the agent is exploring and has a memory of all the locations he was in previously. The goal in this game is to reach the reward (@), so the agent is running around the map until it finds it. At first, it is rather random, but after it finds the reward for the first time, it starts to update
<FromGitter>
... its "memory" so that it can always find the optimal path towards it. Same goes for the punishment (x), it learns to avoid it
jokke has joined #crystal-lang
<FromGitter>
<bew> pretty cool
<FromGitter>
<bararchy> It is :)
<FromGitter>
<ArtLinkov> Yeah, it's quite a powerful algorithm because its quite cheap resource-wise
<FromGitter>
<bararchy> @bew If you are interested in seeing more examples, here is a Google mind Q-Learning playing ATARI => https://www.youtube.com/watch?v=V1eYniJ0Rnk&vl=en ⏎ Overall it's the same logic just on different problems
<FromGitter>
<ArtLinkov> @bararchy this is deep q-learning :) ⏎ But yeah the basic concept is the same
faustinoaq has quit [Ping timeout: 248 seconds]
<FromGitter>
<bajro17> Hi
<FromGitter>
<bajro17> Do you have any package for http2
<FromGitter>
<bew> I got the idea 5 hours ago, so there are not *a lot* of thought, but I like it so far, I can't wait feedback :P
<FromGitter>
<bararchy> @bew
<FromGitter>
<bew> ?
<FromGitter>
<bararchy> basiclly this means all Tuple + Struct are always on the stack until used, even when "stored" in an array or class ?
<FromGitter>
<bararchy> until called i mean
<FromGitter>
<bew> no, (named)tuple, structs & other value types are on the stack by default, it's when they are embedded in a type (e.g: the `Container` class in the example, or in an array of structs) that the struct is no longer on the stack, but copied in-place in the memory area of the container
<FromGitter>
<j8r> e.g. `it routes /`, `it routes /home`...
<FromGitter>
<hmans> @j8r I know. Focus so far was on building that TestRequest scaffolding.
<FromGitter>
<hmans> Actually, let me clarify, since I don't agree fully.
<Yxhuvud>
there are some stuff I'm really missing from rspec, like the ability to define inline methods scoped to a describe scope.
<Yxhuvud>
*spec. rspec has it of course.
<FromGitter>
<hmans> In this example, I want to prove that Crappy's routing works, and that's what I'm doing. It's different from proving that /foo returns "Foo!".
<FromGitter>
<hmans> The "any example should only ever run one expectation" school of thinking is a bit shortsighted IMO.
<FromGitter>
<hmans> (Hi, I give software testing workshops for a living :b)
<FromGitter>
<j8r> Yes but I one route work on others not, would be harder to debug which one is KO
<FromGitter>
<hmans> @yxhuvud Yes, I noticed that internally, Crystal's spec seems to tick quite differently from RSpec. Apparently, examples don't run on instances of anything? I was sort of expecting `describe` et al were macros that create classes (I haven't looked at the source yet)
<FromGitter>
<hmans> I tried to implement a `let` macro and were stopped by the compiler because I can't create new `def`s in whatever context `describe` ends up setting up. Need to dive deeper at some point.
<Yxhuvud>
tbh I'd rather have methods than let, especially as methods give me everything I want of let :)
<FromGitter>
<hmans> Well, you can't write methods within a `describe` block, either, and when you do it outside, you lose the nice cascading nature of RSpec's `let`s.
<FromGitter>
<hmans> (Ignoring the fact that `let` does solid memoization out of the box that you would have to implement yourself over... and... over... again)
<FromGitter>
<hmans> (which would be hard to do because you don't even have an instance of anything to set instance variables on.)
<FromGitter>
<hmans> It's good that Crystal has `spec`, but looking at Crystal's own spec suite, it seems it's using it mostly like one would use *Unit, MiniTest et al, just with things named a little differently
<FromGitter>
<j8r> But Redis is still useful if you have different languages
<FromGitter>
<j8r> There is also LevelDB
That_Guy_Anon has joined #crystal-lang
avdi has quit []
avdi has joined #crystal-lang
OvermindDL1 has quit []
OvermindDL1 has joined #crystal-lang
rohitpaulk has joined #crystal-lang
<FromGitter>
<girng> @j8r not sure. i heard redis is very fast and trusted in the industry. i used it with nodejs for in-memory database storage and horizontal scale w/ pub sub too. i take a look at rocksDB though, thank you
<FromGitter>
<girng> good morning btw.
manveru has quit []
manveru has joined #crystal-lang
<FromGitter>
<hmans> @girng \o/
danzilio has quit []
danzilio has joined #crystal-lang
DTZUZU has quit [Quit: WeeChat 1.9]
DTZUZU has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 240 seconds]
<FromGitter>
<girng> =]
WA9ACE has quit []
WA9ACE has joined #crystal-lang
<FromGitter>
<girng> `code block` if value == true
<FromGitter>
<girng> is it possible to have multiple code blocks in there and still use 1 `if value === true`?
<FromGitter>
<Blacksmoke16> hm?
<FromGitter>
<girng> for example
<FromGitter>
<girng> db.query("QUERY"), db.query("QUERYHERE") if variable == true
<FromGitter>
<girng> is something like that possible in crystal?
<FromGitter>
<bew> You should read the Crystal parser, you'll learn a lot
<FromGitter>
<bew> Yeah that too I forgot about it
<FromGitter>
<girng> hell yeah
<FromGitter>
<girng> freaking awesome
<FromGitter>
<bew> @girng it's like in C actually (another dark syntax! \o/)
<FromGitter>
<hmans> Well, note that it printed "bar" first.
<FromGitter>
<hmans> The second puts is an argument to the first puts.
<FromGitter>
<bew> It'll return the last expression in the parentheses
<FromGitter>
<hmans> So please do not ever follow that example with the commas.
<FromGitter>
<girng> @hmans oh good catch didn't even notice that lol
<FromGitter>
<hmans> (It works fine when you replace that comma with a semicolon, though. Good enough.)
<FromGitter>
<girng> i wonder why it does that with commas, since puts foo was first
<FromGitter>
<Blacksmoke16> `The second puts is an argument to the first puts.`
<FromGitter>
<girng> oh argument
<FromGitter>
<girng> yeah, got it
<FromGitter>
<girng> oh god yeah, im not gonna do that
<FromGitter>
<girng> coool to know i was just curious thinking about syntax thats all
<FromGitter>
<girng> im having an issue with socket.remote_address however ⏎ my game instance server makes a connection to my master server. when it does, it sends a key to authenticate itself as master server. ⏎ then my master servers stores that connections socket.remote_address, in a hash. ⏎ ⏎ except, t he socket.remote_address is returning `127.0.0.1:57488`, but the game instance server is started on
<FromGitter>
<girng> but 127.0.0.1:57488 isn't the server that i created, i'm just using that crystal game instance to connect to master server to create a tcp connection. the master server should know the real ip/port of the game instance server
<FromGitter>
<hmans> Is all of that happening on your local machine?
<FromGitter>
<girng> i created the server on 0.0.0.0:9301
<FromGitter>
<girng> yah
<FromGitter>
<girng> but im making a tcp connection not waiting for master server. maybe that's why?
<FromGitter>
<hmans> When your master sees your instance server's incoming connection as 127.0.0.1:57488, that's exactly what it is. It means the connecting client is on interface 127.0.0.1 and port 57488.
<FromGitter>
<girng> but that's not where the game instance server is running so how the hell is that possible
<FromGitter>
<girng> it's running on 0.0.0.0:9301
<FromGitter>
<girng> all i want to get is the IP and port
<FromGitter>
<hmans> Any outgoing TCP connection is assigned a random-ish port number, and that's what the server sees when he inspects the client's `remote_address`.
<FromGitter>
<mjago> @sdogruyol Thanks for the compiments about Sonicri ~ the idea is to get it onto a raspberry pi with touch screen control, but not there yet 😉
<FromGitter>
<girng> yes i understand but it should be possible to still get the server it's on. not just the ephemeral port/ip
<FromGitter>
<girng> so i have to send the ip:port of the game instance through tcp, to the master server?
<FromGitter>
<girng> but shouldn't the master server already know about my ip and port. makes no sense
<FromGitter>
<girng> i mean the TCP connection has been ESTABLISHED
<FromGitter>
<bew> Huh no, that's 2 different things the game server listening to some port and that same gameserver connecting to a master server. These 2 connections are unrelated
rohitpaulk has quit [Ping timeout: 240 seconds]
<FromGitter>
<girng> how are those unrelated
<FromGitter>
<bew> So yeah you need to send the data if you need it
<FromGitter>
<girng> the game server is connecting tot he master server
<FromGitter>
<girng> the game server should know the ip/port of that connection
<FromGitter>
<girng> if they established a connection (which i already did)
<FromGitter>
<bew> But you have the gameserver listening to the port 9301 also, right?
<FromGitter>
<girng> yeah
<FromGitter>
<bew> Then you have 2 separate / related things
<FromGitter>
<bew> 1) The gs listening
<FromGitter>
<bew> 1) The gs connection to the master
<FromGitter>
<bew> Grr 2.
snsei has quit [Remote host closed the connection]
<FromGitter>
<bew> The connection to master is not linked in any way to the gs listening
snsei has joined #crystal-lang
<FromGitter>
<bew> *unrelated
snsei has quit [Remote host closed the connection]
snsei has joined #crystal-lang
<FromGitter>
<girng> makes sense
snsei has quit [Remote host closed the connection]
<FromGitter>
<girng> however, if i start the connection on a vps, and block all ports except for 9301
snsei has joined #crystal-lang
<FromGitter>
<girng> how in the hell am i supposed to connect to the master SERVER
<FromGitter>
<girng> from the game server...
snsei has quit [Remote host closed the connection]
<FromGitter>
<bew> The gs could listen on many ports, it doesn't matter
<FromGitter>
<bew> Ah
snsei has joined #crystal-lang
<FromGitter>
<bew> But they are on the same machine right?
snsei has quit [Remote host closed the connection]
<FromGitter>
<girng> now,but not when i buy the VPS
snsei has joined #crystal-lang
<FromGitter>
<bew> Huh why not? You're buying multiple vps and connecting them together?
<FromGitter>
<girng> yeah i buy 1 vps for master server, block all ports except 9300. then buy 2 smaller vps for game instance servers, put 1 west/east USA
snsei_ has joined #crystal-lang
<FromGitter>
<girng> those game instance server connect to master server an authenticate themselves
<FromGitter>
<girng> and those game instance servers, only allow 9301 port for other players to connect
<FromGitter>
<bew> That's ok
<FromGitter>
<girng> so how do i dynamically take care of all this `127.0.0.1:57488` bologna is beyond me
<FromGitter>
<girng> when the port # changes..
<FromGitter>
<girng> randomly
<FromGitter>
<girng> lmfao.
<FromGitter>
<bew> Make your gs listen to that port (for incoming request)
<FromGitter>
<bew> When you connect to the master server it's an outgoing request, so it should work normally
<FromGitter>
<girng> different than local machine (what i'm dealing with now)?
<FromGitter>
<bew> It seems like you're only restricted to 1 port for incoming requests
<FromGitter>
<bew> But you shouldn't be restricted for outgoing requests (from your server to somewhere else)
<FromGitter>
<girng> yeah, correct
<FromGitter>
<girng> just incoming ports i close all, and open certain ones
snsei has quit [Ping timeout: 276 seconds]
<FromGitter>
<drum445> When hosting a crystal app for production (it's using kemal) can I use it similar to go, that is compile to a binary and run on a port on my server, or do I need to put it behind Nginx?
<FromGitter>
<drum445> Would love to confirm that I can just run ./app on my server
<FromGitter>
<bew> So there's no problem, you can make an outgoing connection to your master server from the gs @girng
<FromGitter>
<bew> And communicate with it (send it the port you're listening on for example)
<FromGitter>
<girng> @bew well, yes but i need the master server to know which ip port that connection is (when the gs makes the connection). ⏎ ⏎ should i just send the ip:port in a tcp message when i authenticate??
<FromGitter>
<bew> You probably can't send the ip, but you can send the port
<FromGitter>
<bew> And the master will find the ip in remote_address
<FromGitter>
<girng> ok
<FromGitter>
<girng> yeah that's what i was thinking
<FromGitter>
<bew> @girng why does it need to know that actually?
<FromGitter>
<bew> To redirect users that first connect to the master, to their nearest gs? (or sth like that?)
<FromGitter>
<girng> my master server stores the game_servers in a hash, and when a user creates a game, master server dose `min_by` and finds least active server to put the player. then the master server sends that ip/port to the connected player so they can join that instance
<FromGitter>
<girng> yeah what you said, basically
<FromGitter>
<bew> @drum445 I think you can just use it directly
<FromGitter>
<drum445> @bew cheers sir, I've been running it directly for a week or so and haven't seen any issues. Was just curious to see if this was ok
<FromGitter>
<girng> i am not sure about authentication though. i want to generate a GUID for the server transfer
<FromGitter>
<bew> I never deployed anything myself in production actually, but I think nginx would be a good idea to have some kind of protection, or more specific regulation of the traffic, etc
<FromGitter>
<bew> @drum445 ^
<FromGitter>
<girng> yes nginx is great for reverse proxy
<FromGitter>
<girng> and the rate limiting and stuff is perfect to put infront of kemal
<FromGitter>
<drum445> any tutorials on how to do that?
<FromGitter>
<drum445> I like the simplicity of running the binary on the server
<FromGitter>
<girng> @faustinoaq damn that looks epic
<FromGitter>
<girng> @faustinoaq i relly want to move to vscode now
<FromGitter>
<girng> 410 to 470 karma, let's c how long it sticks
<FromGitter>
<fridgerator> @faustinoaq is it easy to get that same set up running in vscode?
<FromGitter>
<fridgerator> or is there some custom stuff going on there
<FromGitter>
<fridgerator> I know you've done a ton of work with vscode plugins for crystal
<FromGitter>
<faustinoaq> @fridgerator @girng Nop, nothing have been done on vscode-crystal-lang extension, this is just Scry, so this should work on other editors as well. ⏎ ⏎ I'm already testing it Sublime and Intellij-Idea as well 😉