<FromGitter>
<jrei:matrix.org> straight-shoota monkey patching HTTP::Server::Context is obviously bad. If I use Kemal, which monkey patch it, your lib, then another one, issues like name clash can raise. And a the end, we don't even know what's stdlib or not
<straight-shoota>
not sure I agree on "obviously bad"
<FromGitter>
<jrei:matrix.org> particularly in this context
<FromGitter>
<jrei:matrix.org> at least, passing a "monkey patchable" context or hash around would be cleaner. Handler could add properties to the hash, which is then fetched by another one
<straight-shoota>
but if you use a session library like http-session there's no reason to use another one which would also occupy the session name
<straight-shoota>
the difference between monkey patching additional properties and a hash is that the latter is more complexity, less performance and errors at runtime
<straight-shoota>
but potential for name collision is the same
<FromGitter>
<jrei:matrix.org> or passing a named tuple or an other more efficient object
<straight-shoota>
doesn't change anything
<FromGitter>
<jrei:matrix.org> so, I don't understand something: what's the point of monkey patching to be reusable on other handlers, if they don't know this added method?
<straight-shoota>
Crystal allows re-opening types for a reason. It should not avoided, if possible. But I do believe it's possible to use it for enhancing types from stdlib (or other libraries)
<straight-shoota>
as long as it's within reason
<FromGitter>
<jrei:matrix.org> I don't see how it is valid here - it can be avoided
<FromGitter>
<jrei:matrix.org> The handlers knowing the added method are custom made by the users, not from stdlib/other libs
<straight-shoota>
yes, so?
<FromGitter>
<oprypin:matrix.org> look let's say you made this library
<FromGitter>
<jrei:matrix.org> So, the SessionManager can be passed to the handler initializer
<FromGitter>
<oprypin:matrix.org> then another person made a competing library that also monkeypatches
<FromGitter>
<oprypin:matrix.org> and then you pull in both of them unknowingly through two different dependencies transitively
<FromGitter>
<oprypin:matrix.org> it will break, right?
<straight-shoota>
@jrei: If you pass the session manager, but not the session, every handler that accesses the session needs to load it
<straight-shoota>
opyrpin: if you do that, probably yes
<FromGitter>
<jrei:matrix.org> straight-shoota unless you call method which pass the session ;)
<FromGitter>
<jrei:matrix.org> could be problematic in some cases
<straight-shoota>
but as long as it's not hard wired to include any of the respective libraries, you can make sure to only include one
<straight-shoota>
if they follow the same API, they could even be interchangeable
<FromGitter>
<oprypin:matrix.org> straight-shoota, no you don't understand
<straight-shoota>
jrei: what method with what session?
<FromGitter>
<jrei:matrix.org> anyway, overall, all of this works. Kemal works, your approach too.
<FromGitter>
<oprypin:matrix.org> there are 2 different session libraries like yours. then a library depending on yours that does some unique thing. then another library depending on the competitor library.
<straight-shoota>
kemal-session does exactly the same thing:
<FromGitter>
<oprypin:matrix.org> some person wants to use these 2 unique libraries at the same time but for an arbitrary reason they cannot
<FromGitter>
<oprypin:matrix.org> they never depended on either of the monkeypatching libs and they can't prevent it
<FromGitter>
<jrei:matrix.org> exactly: I'm on Kemal-session, I want to migrate to your lib - boom
<straight-shoota>
and what would be the purpose of using two different session libraries?
<straight-shoota>
no boom
<FromGitter>
<oprypin:matrix.org> straight-shoota, again you don't understand
<FromGitter>
<jrei:matrix.org> try it before migrate it in production
<straight-shoota>
remove kemal-session, add http-session, migrate your app and dependencies
<FromGitter>
<oprypin:matrix.org> unique library C uses session library A
<FromGitter>
<oprypin:matrix.org> unique library D uses session library B
<FromGitter>
<oprypin:matrix.org> i want to use library C and library D
<FromGitter>
<oprypin:matrix.org> i can't
<FromGitter>
<jrei:matrix.org> what @oprypin says is true too
<straight-shoota>
when C depends on session management A and D depends on session management B, there's no way they are both going to work together, no matter if A and B could work alongside each other or no
<FromGitter>
<oprypin:matrix.org> who says they work together
<FromGitter>
<oprypin:matrix.org> they are in completely different code paths
<FromGitter>
<oprypin:matrix.org> but it still breaks
<FromGitter>
<oprypin:matrix.org> very simple real example
<FromGitter>
<jrei:matrix.org> it is easier to keep 2 libs alongside and migrate progressively, particularly for huge monoliths
<FromGitter>
<oprypin:matrix.org> library C is a library interfacing with GitHub and library D is interfacing with GitLab
<FromGitter>
<oprypin:matrix.org> i use both in 1 app. not at the same time, sure
<straight-shoota>
is that the entire example?
<straight-shoota>
then I don't understand why these libraries are coupled to a session system at all, and why you wouldn't want to use the same sessions for both?
<FromGitter>
<jrei:matrix.org> they need to, they abstract this logic I guess
<straight-shoota>
what logic?
<FromGitter>
<jrei:matrix.org> the point is still valid: you could have a hug monolith with different parts needing different equivalent libs, which has their pros/cons
<straight-shoota>
this would need to be libraries that not only connect to external services, but also handle the HTTP processing directly
<straight-shoota>
there's always potential for conflict when several libraries are suppose to work together. That's why http-session is proposal for a standardized interface.
<straight-shoota>
I mean an even more realistic scenario than unrelated sessions in different code paths is libraries sharing access to the same sessions
<straight-shoota>
because different features of a website require storing data in the user session
<straight-shoota>
that's a huge potential for conflict
<straight-shoota>
hence, the recommendation to prefix session properties with the shard name
<straight-shoota>
For example: there's another shard I'm working on which provides authentication via OpenID Connect. Its session properties are prefixed with `openid_connect_`.
<straight-shoota>
but it also doesn't automatically require http-session once you use openid-connect
<straight-shoota>
so you can easily integrate it with a different session mechanism
<FromGitter>
<jrei:matrix.org> the library can't be standard, Lucky does it way, Amber too. For Athena, I don't think it will be an idiomatic way
<straight-shoota>
I'd definitely like to see alternative approaches to the session management
<FromGitter>
<jrei:matrix.org> one issue is it depends of the framework
<FromGitter>
<jrei:matrix.org> yours is the best for Kemal
<straight-shoota>
yeah, but I just find all existing solutions, be it lucky, amber, kemal-session lacking type safety
<FromGitter>
<jrei:matrix.org> I think for Athena, with its typing philosophy, will make a session only available for certain paths
<straight-shoota>
I mean this is crystal, not ruby or PHP, yet they store session values by string names
<straight-shoota>
which doesn't make any sense to me
<FromGitter>
<jrei:matrix.org> but with your approach all paths using a `HTTP::Server::Context` can call `session` methods
<straight-shoota>
that's the beauty of it. It just works. Simple.
<FromGitter>
<jrei:matrix.org> but not very type safe then 😕
<straight-shoota>
why not?
<FromGitter>
<jrei:matrix.org> ideally, a session should only be available on paths which require them, not all - of course
<straight-shoota>
why?
<straight-shoota>
some handlers may not need request or response, yet it's still available to all
<FromGitter>
<jrei:matrix.org> they don't need it - calling it by mistake is an error
<straight-shoota>
sry, I don't follow. What is the mistake?
<FromGitter>
<jrei:matrix.org> yeah, again, that's not how Athena, Lucky or Amber work
<FromGitter>
<jrei:matrix.org> I guess it is hard to make a compile time error instead of a runtime one
<straight-shoota>
you mean when a handler accesses the session but the session handler didn't initialize it=
<straight-shoota>
?
<FromGitter>
<jrei:matrix.org> with handlers, à la Kemal/stdlib, it is not doable
<FromGitter>
<jrei:matrix.org> but with the Controller approach I think it could
<straight-shoota>
yeah, well that's an entirely different architecture
<straight-shoota>
so something like this could be an alternative approach for handlers: https://carc.in/#/r/ah5e
<FromGitter>
<jrei:matrix.org> yes that's what I was proposing afterwards
<FromGitter>
<jrei:matrix.org> one issue is if we have, CustomHandler -> stdlibHandler -> CustomHandler - it won't work
<straight-shoota>
why not?
<straight-shoota>
the external interface for the handler chain is just call(context)
<FromGitter>
<jrei:matrix.org> because the `call(context : HTTP::Server::Context, session : T)` is not present in other handlers
<straight-shoota>
call_next(context) would obviously call the interface method, not the internal overload with session parameter
<FromGitter>
<jrei:matrix.org> ha, you want to keep both the monkey patch and have this method call?
<FromGitter>
<jrei:matrix.org> right, indeed...
<straight-shoota>
I don't think you would combine both approaches
<FromGitter>
<jrei:matrix.org> the handlers approach is such a pain for auth :/
<straight-shoota>
is it?
<FromGitter>
<jrei:matrix.org> yeah, I've an app using Kemal, we needed custom macros/methods to put routes behind auth
<FromGitter>
<jrei:matrix.org> *I had
<straight-shoota>
ah yeah for custom logic you need a macro in order to exit the handler with next
* FromGitter
* Blacksmoke16 is glad he went with event/listener approach
<FromGitter>
<jrei:matrix.org> not sure it has to do with the paradigm
oprypin has quit [Quit: Bye]
oprypin has joined #crystal-lang
<FromGitter>
<jrei:matrix.org> more to do of the way to declare routes and grouping them. ⏎ Handler has none of this concept, Kemal only the first
<straight-shoota>
If only the event/listener approach would be easily approachable :P
<straight-shoota>
No seriously, I like it. But it's more complexity to set up
<FromGitter>
<jrei:matrix.org> agree too, IMHO not *needed*
<FromGitter>
<Blacksmoke16> > more to do of the way to declare routes and grouping them. ⏎ > Handler has none of this concept, Kemal only the first ⏎ ⏎ yes, but if you had a way to attach metadata to a route *AND* know what route a current request would invoke, you can more easily handle that side of things [https://gitter.im/crystal-lang/crystal?at=603c4189457d6b4a94950262]
<FromGitter>
<jrei:matrix.org> why not use regular callbacks?
<FromGitter>
<Blacksmoke16> > *<straight-shoota>* No seriously, I like it. But it's more complexity to set up ⏎ ⏎ for sure, benefit is it's not required, and fairly easy concept when you get the how things work. is a graphic/dedicated walkthru how it works
<FromGitter>
<Blacksmoke16> i.e. only need to know it if you need it
<FromGitter>
<Blacksmoke16> how would that work?
<FromGitter>
<Blacksmoke16> but yea, im not proposing the stdlib adopt it
<FromGitter>
<jrei:matrix.org> instead of emitting an event, call the methods which will receive it in place
<FromGitter>
<jrei:matrix.org> works fine for simple cases. I believe more complex ones would benefit more with a service like RabbitMQ
<FromGitter>
<Blacksmoke16> got an example?
<FromGitter>
<Blacksmoke16> because an event to tap into the request/response life-cycle is not really the same idea as using rabbit
<FromGitter>
<Blacksmoke16> each listener is stored as a proc (callback), and invoked?
<FromGitter>
<jrei:matrix.org> ok! So that's just a shortcut
<FromGitter>
<jrei:matrix.org> yeah
<FromGitter>
<Blacksmoke16> the dedicated type is needed to support dependencies
<FromGitter>
<Blacksmoke16> i.e. each request gets its own listener instance, which comes with its own set of dependencies etc
<FromGitter>
<jrei:matrix.org> I see, interesting
<FromGitter>
<jrei:matrix.org> one way to solve the global handlers limitations, it so have a list of handlers per controller/route
<FromGitter>
<jrei:matrix.org> at the end, Athena approach or others, that's the missing granularity which hurts
postmodern has joined #crystal-lang
<FromGitter>
<jrei:matrix.org> ...in Kemal
<FromGitter>
<jrei:matrix.org> or, HTTP::Server
<FromGitter>
<Blacksmoke16> granularity of what?
<FromGitter>
<Blacksmoke16> like knowing what listeners should be scoped to a particular controller/route?
<FromGitter>
<jrei:matrix.org> being able to execute a common set of actions for a set of routes
<FromGitter>
<jrei:matrix.org> yes exactly
<FromGitter>
<Blacksmoke16> yea by default in Athena, and esp for `HTTP::Handler`, the listener would be invoked for every route. But there are ways around that. E.g. https://athenaframework.org/cookbook/listeners/#pagination this noops if the route doesn't have the related annotation
<FromGitter>
<Blacksmoke16> could also do a similar thing with modules. I.e. return unless the controller class includes some "interface" module or what haveyou
<FromGitter>
<Blacksmoke16> could use that in the stdlib case as well
<FromGitter>
<Blacksmoke16> well maybe as part of lucky/amber given stdlib/kemal doesnt have controller concept so there wouldnt be a thing to add it to
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
andremedeiros has quit [Read error: Connection reset by peer]
andremedeiros has joined #crystal-lang
<watzon>
Any ideas on the most efficient way to make a Slice as small as possible by eliminating trailing null bytes?
<watzon>
I guess I basically need `String#strip`, but for enumerables
<FromGitter>
<naqvis> so you better do a quick benchmark to check that
<FromGitter>
<void-witch> how do i run specs with shards? `crystal spec` gives me errors about missing libraries
<FromGitter>
<naqvis> did you run `shards install`?
<watzon>
Thanks @naqvis :)
<watzon>
Turns out the bytes are actually in big endian format though, so I was able to just use index to find the first non null byte and then get a new slice from that position.
<FromGitter>
<naqvis> yeah, that would definitely work
<FromGitter>
<naqvis> another thought i had was doing something like binary search to find the first index of null byte and then do the truncation from that
<FromGitter>
<naqvis> as binary search like algorithm will prevent sequential traversal
<FromGitter>
<naqvis> for smaller slice, sequential traversal is ok, but for bigger ones, that will have the benefit
<watzon>
Yeah, in this case we're dealing with 8 bytes though so it's not a big deal
<watzon>
Also figured out that my generated abstract classes aren't useless either
<watzon>
I need a way to determine the returned type of an RPC method, and that's where this comes in. Granted I'm now up to 42000 lines of generated code.
_ht has joined #crystal-lang
hendursa1 has joined #crystal-lang
hendursaga has quit [Ping timeout: 268 seconds]
hendursa1 has quit [Ping timeout: 268 seconds]
DTZUZU has quit [Read error: Connection reset by peer]
hendursaga has joined #crystal-lang
DTZUZU has joined #crystal-lang
andremedeiros has quit [Read error: Connection reset by peer]
andremedeiros has joined #crystal-lang
<frojnd>
Hi there. What would be equivalent to the bash's `grep -B 1 "$date" file.ics` in crystal? Basically I would like to grep a line but above the one that matches "$date"
<straight-shoota>
maybe sth like `last_line = nil; File.each_line("file.ics") do |line| if line ~= date then puts last_line; last_line = line end`
andremedeiros has quit [Read error: Connection reset by peer]
andremedeiros has joined #crystal-lang
andremedeiros has quit [Read error: Connection reset by peer]
andremedeiros has joined #crystal-lang
postmodern has quit [Quit: Leaving]
Xeago has quit [Ping timeout: 256 seconds]
Xeago has joined #crystal-lang
<frojnd>
straight-shoota: what is `~=` in crystal lang I get: `unexpected token: =`
<FromGitter>
<Blacksmoke16> it's `=~`
<frojnd>
Ok
<straight-shoota>
sry, typo
<frojnd>
Np
<frojnd>
What's called this `=~` it seems it doesn't match date where date is date="2021.5.5" in a string like this`some string blabla date=2021.5.5`
<FromGitter>
<jrei:matrix.org> that's a regex
<FromGitter>
<jrei:matrix.org> you need to add wildcards
<frojnd>
Hm I have this regular expression: `.*\\n\K.*(?=\\n)` I tried in regex 101 and it works as it should. But when I try this with .match I get nil: `/.*\\n\K.*(?=\\n)/.match("DESCRIPTION:4 blaallala\nblalal alalala\nbla bla\nfoo bar\n»Hlorem ipsum« (baz baz)") I expect `foo bar`
<frojnd>
I would like to match "foo bar" which is in the last \n
<frojnd>
Between last two \n
<straight-shoota>
you need to set the multiline flag for that
<straight-shoota>
`/.*\n\K.*(?=\n)/m`
<frojnd>
I see
<frojnd>
Thank you
<FromGitter>
<watzon> @oprypin great job on the mkdocs changes. The tourmaline docs are looking better than ever.
<frojnd>
Just wondering... I get `reg = Regex::MatchData("foo bar")` how do I get "foo bar" as a string. I did it as reg.to_a.first but is there any other better way?
<FromGitter>
<Blacksmoke16> `reg[0]`
<FromGitter>
<Blacksmoke16> or depending on the context you might be able to just do like `$1`