Administrator
|
Master is shaping up for a release. If you know of anything amiss, please let the list know.
We have a million modules now. I think the best way to help people make sense of them (until someone makes an awesome scala artifact browsing site with unfiltered) is to write a readme in their project directories, with at least a sentence description. We can do this before or after release, the main thing is that it is on github and is linked from the main project readme. We need more notes for this release. Most of those are mine to write, but if you've added anything since 0.2.1 that's in master please reference it in notes/0.2.2.markdown. The core feature in 0.2.2 is an Intent skeleton that should work for any purpose because it is really just another name for PartialFunction. Intents can describe a request cycle but they can also describe just the beginning of it, or they can describe web socket communication ... etc. It's up the package (e.g. unfiltered.netty.cycle, unfiltered.netty.channel) to define a good Intent type to be used in its Plan trait. Regarding the & object. It's awesome and I've added it to the new "util" module. It's in fact required to do much good with the new channel Plan (because our request extractors only give you HttpRequest[T]) but the real win will be when we remove all the annoying HttpRequest elements of the response tuples of nearly every extractor. That's going to be a big breaking change for app code so it can't happen until 0.3.0, but with 0.2.2 people can start writing case Path("/",_) & req => instead of case Path("/", req) => to prepare for it. Nathan |
I tested merging master into the security branch and things seemed to apply cleanly. Is it cool to add security to master for this release? I see cookies made it in. & looks pretty interesting. very dsl-ish
|
I was going to suggest (or ad) a lazy parameters val to HttpRequest. I haven't added it because I think it's odd it doesn't exist. Any reason why? I understand that you might want people to use the param extractors, but I have getting into writing things like
case (Path("/foo", User(user)) => ResponseString("Hi " + user.name + "! Your phone number is: " + user.phone) And it would be easier to write the User extractor if the request object had a params map. Any chance of adding that to 0.2.2? Dustin On Wed, Oct 20, 2010 at 7:43 AM, soft_props [via Databinder] <[hidden email]> wrote: I tested merging master into the security branch and things seemed to apply cleanly. Is it cool to add security to master for this release? I see cookies made it in. & looks pretty interesting. very dsl-ish |
In reply to this post by soft_props
Also, I'll add some docs into the Scalate module.
D On Wed, Oct 20, 2010 at 9:39 AM, Dustin Whitney <[hidden email]> wrote: I was going to suggest (or ad) a lazy parameters val to HttpRequest. I haven't added it because I think it's odd it doesn't exist. Any reason why? I understand that you might want people to use the param extractors, but I have getting into writing things like |
Administrator
|
In reply to this post by soft_props
On 10/20/10 1:43 AM, soft_props [via Databinder] wrote:
I tested merging master into the security branch and things seemed to apply cleanly. Is it cool to add security to master for this release? Is it possible to write tests for the https interface? Could we put a self-signed certificate in the repository, and then test against it with Dispatch configured to accept it? (That should probably be an operator in Dispatch, too.) Or are you already using this from some project? I'm not so worried about it breaking, it's just that I don't like to add something to the library that hasn't had any code built against it. Nathan
|
I'll write tests this tonight. I wanted to try to get in the netty ssl support too if we can make this a go. Was there a date/day you had planned for a release. I might be taking a weekend escape with wileen in a cabin in upstate ny this weekend, though I can always tether :)
|
Administrator
|
On 10/20/10 10:46 AM, soft_props [via Databinder] wrote:
> I'll write tests this tonight. I wanted to try to get in the netty ssl > support too if we can make this a go. Was there a date/day you had > planned for a release. I might be taking a weekend escape with wileen > in a cabin in upstate ny this weekend, though I can always tether :) I'd like to do this release in the next few days. The try/catch for MatchError needs to go away. Nathan |
Any thoughts on the parameters map I mentioned above?
D On Wed, Oct 20, 2010 at 4:51 PM, n8han [via Databinder] <[hidden email]> wrote:
|
Administrator
|
In reply to this post by Dustin Whitney
On 10/20/10 3:39 AM, Dustin Whitney [via Databinder] wrote:
I was going to suggest (or ad) a lazy parameters val to HttpRequest. I haven't added it because I think it's odd it doesn't exist. Any reason why? I understand that you might want people to use the param extractors, but I have getting into writing things like It's hard for me to say without seeing User, but I think the Params object should handle this scenario well. object User { def unapply[T](req: HttpRequest[T]) = { val Params(pmap) = req Some(User.fromMap(pmap)) } } Nathan |
On Wed, Oct 20, 2010 at 5:03 PM, n8han [via Databinder] <[hidden email]> wrote:
Yeah, that's what I've been doing (essentially). I just think there's nothing really wrong with object User { def unapply[T](req: HttpRequest[T]) = { Some(User.fromMap(req.parameters)) } }
|
Administrator
|
On 10/20/10 11:26 AM, Dustin Whitney [via Databinder] wrote:
> Yeah, that's what I've been doing (essentially). I just think there's > nothing really wrong with > > object User { > def unapply[T](req: HttpRequest[T]) = { > Some(User.fromMap(req.parameters)) > } > } You can also say Params.unapply(req).map(User.fromMap) I don't think it's wrong to have a `parameters` field, but I'm weary of adding different interfaces to do the same thing. In general the purpose of HttpRequest[T] is to expose a uniform interface for extractors to act on (and build on each other), with the theory that using extractors is nicer. If it's not nicer we need to revisit that assumption. I ran into something similar with the netty.channel.Plan. I was going to write extractors to get at the Channel. But then after the trouble we had with side effects from multipart posts, I'm thinking now that we should not create extractors that are unlikely to be useful in a pattern matching expression. So, what I ended up with was a subtype of HttpRequst that users are expected to write code against. But I'd rather think about it a bit more before heading that direction with HttpRequest itself. We have a good interface to parameters as it is; if we're going to change the mission of HttpRequest a bit, 0.3.0 will be a good time to do that when we are pulling the references to it out of all the base level extractors. Nathan |
In reply to this post by soft_props
I already have some Netty SSL code that could be added pretty easily, so if you're not already done, I'd be happy to put it in.
|
Administrator
|
On 10/22/10 11:29 AM, Dag Liodden [via Databinder] wrote:
> I already have some Netty SSL code that could be added pretty easily, > so if you're not already done, I'd be happy to put it in. That would be awesome, you could do that in the security branch at any time. I'm still planning to do a release of what's in master, just haven't gotten to it yet this week. Nathan |
Administrator
|
Eh, take two. I made a lot more changes to master today. I had given up on really fixing the response types as originally planned, but I finally hit the right structure for it.
Now you can write response functions that require a certain underlying response type. ResponseFunction takes a single type parameter for this purpose. The existing response functions which depend only on the HttpResponse interface extend ResponseFunction[Any]. These can be combined (using ~>) with a more specific response function, and the resulting narrowed type is checked against the one defined for the intent. Also re-plumbed the plan implementations for Netty, so that cycle depends on the richer request binding used by channel, eliminating a lot of duplicated code. And finally, I refactored the Netty servers to be more like the Jetty server classes. Server is a base trait, and Http is a (superficially) immutable case class. Handlers (plans) are added to the server with a handler method. This was a fair bit of stuff so I'm not going to release right away. Give a heads up if you find anything on master that's broken or just ugly! Nathan |
Whoah, that's a pretty massive refactor! :)
|
Gah! Getting messages these kind of late. I was away all weekend. I'm about 80% there already with netty ssl/trust store support :/ Sry I didn't see yr msg sooner daggerrz. Refactorings look nice nathan.
|
Hehe,
Go ahead and finish / push what you have, and I'll compare it with what I've done earlier. :) Dag
On Mon, Oct 25, 2010 at 2:53 PM, soft_props [via Databinder] <[hidden email]> wrote: Gah! Getting messages these kind of late. I was away all weekend. I'm about 80% there already with netty ssl/trust store support :/ Sry I didn't see yr msg sooner daggerrz. Refactorings look nice nathan. |
Will do tonight. Thanks Dag!
|
In reply to this post by n8han
Took a closer look and it still looks good (+ my code started working!). Some remarks:
1. I like the way Channel plans now can return Unit and choose to respond via underlying.respond() later. However, it is obviously not possible to have some patterns return Unit and others a Responder (in the same plan), and as the Netty server does not support contexts (yet), this renders the Netty module pretty inflexible. :) I suppose the only right way to fix this is implementing contexts.
2. I'm not sure it's a good idea to have the Plan object + traits called by the same name in all packages (i.e netty.channel.Plan, netty.cycle.Plan and filter.Plan). Maybe it's just me struggling a bit with the nomenclature here, but I'm already having trouble juggling Plan, Intent and Planify and wouldn't mind seeing a "NettyChannelPlan". Planify obviously needs to have a stable name, though, som maybe it would be inconsistent to rename the others...
3. I like the new option to chain general responders with specific ones - this is neat! :) defaultResponse( unfiltered.response.Server("Scala Netty Unfiltered Server") ~> rf ~> closer
) 4. The join method in netty.Server is a little fishy: def join(): this.type = { def doWait() {
try { Thread.sleep(1000) } catch { case _: InterruptedException => () } doWait() } Runtime.getRuntime.addShutdownHook(new Thread { override def run() { Server.this.stop() }
}) doWait() this } For one, it never returns, so it should be Unit and second, I'm not sure what it's supposed to do. Third, I think a while(true) would be more readable than the current tail-recursive one. ;)
On Mon, Oct 25, 2010 at 8:50 AM, Dag Liodden <[hidden email]> wrote:
|
Administrator
|
On 10/25/10 11:44 AM, daggerrz [via Databinder] wrote:
1. I like the way Channel plans now can return Unit and choose to respond via underlying.respond() later. However, it is obviously not possible to have some patterns return Unit and others a Responder (in the same plan), I don't know, will this work? Http(8080).handler( unfiltered.netty.channel.Planify(...) ).handler( unfiltered.netty.cycle.Planify(...) ) I guess not as the cycle plan is always going to return NotFound if the request doesn't match. But if it didn't... ? and as the Netty server does not support contexts (yet), this renders the Netty module pretty inflexible. :) I suppose the only right way to fix this is implementing contexts. As long as the handler-as-Plan foundation supports adding that flexibility later, I think we're in good shape.
My thinking is that the class name should not repeat information that is the package name, for two reasons: 1. I haaaaaaaate redundancy 2. There is less reason to import all or some of the package into scope, and a good reason not to (collisions). This is probably something that breaks down along ide/non-IDE lines. The convention influenced by Java IDEs is to more or less ignore the namespaces offered by packaging and expect class names to be unique across a classpath, so you can start typing it and the api will add an import statement for you. Then you end up with a ton of imports at the top of the file that nobody wants to see or think about, so they're collapsed. I'm trying to employ a convention that is easy for the API users to type without code completion, though I'm not sure how successful it is. I have a few doubts about not abbreviating "unfiltered" as a base package name since we see that a lot. In 2.7.7 you could import it and then refer to its subpackages, but of course that had server interoperability problems with the domain-style package scheme. I'm not sure if there's a way to do something similar in 2.8. To be honest, even with emacs I am getting tired of not being about to tell between four open buffers named servers.scala, a somewhat related problem. So, I'm struggling with this decision too, in terms of working with the Unfiltered source. But as far as *using* the library goes, I find the naming scheme to be very easy to remember and type. Once you learn it you can apply it across different modules to guess the names and you'll usually be right. ... In my defense, "it works!". :) It is supposed to keep the jvm from exiting if you have run your app from the command line, and it does that. It also invokes stop so that you can gracefully shut down the server on an int or term signal. As far as the method signature goes, it's wrong for the current Netty implementation but it's right for the Jetty implementation which shares that interface, and for Netty we'll implement it fully at some point, I hope. I just need to look at Jetty's source to see what they are doing to process signals; it's probably longer and uglier than just a shutdown hook, but it's worth implementing to have a method that does return. If that can't be done we can change the interface, but for the current release I wanted the basic functionality in there (with a javadoc warning) in case I need to use it soon. Nathan
|
Free forum by Nabble | Edit this page |