Upgrading RC2 to Trunk

22 views
Skip to first unread message

Nicholas Piasecki

unread,
Feb 9, 2009, 6:21:05 PM2/9/09
to Castle Project Users
Hello, and apologies for the forth-coming semi-rant,

I'm currently evaluating the feasibility of upgrading a 2-year-old
MonoRail Web site running RC2 to the latest or near-latest trunk. Now,
I don't expect upgrading from a 2-year-old binary to a new one to
"just work," but when moving from a "release candidate," I really
don't expect to see that many changes, at least not without a clearly
defined migration. The number of breaking changes, however, is
astounding. Here's a sample overview:

* MonoRailHttpHandler.CurrentContext seems to be gone. This is huge
and causes a lot of problems for this site. Is the preferred method to
simply favor the ASP.NET-provided HttpContext.Current property to
access these variables?

* IRailsEngineContext has changed to IEngineContext. Irritating, but a
find and replace is simple enough. Similarly, ExecuteEnum has changed
to ExecuteWhen. A silly breaking change, but okay.

* The IFilter interface has changed to include an IControllerContext,
which seems to be new.

* IsPreConditionSatisified() on WizardStepBase is now public instead
of protected, breaking any code that overrode that method. Simple
enough to fix.

* WizardStepBase has lost the Redirect() overload that took a single
URI, which was useful for redirecting to external sites like PayPal or
Google Checkout. I suppose the new replacement is RedirectToUrl().

* The Initialize() method of WizardStepPage is gone. What is the
replacement? The constructor?

* The interface for IWizardController has changed in that the GetSteps
() method returns an interface instead of an concrete class. Fair
enough.

* The Initialize() method on Controller is now public instead of
protected. Okay.

* The SelectMethod() method on SmartDispatcherController has gained an
additional parameter, actionType. Straight forward.

* The IParameterBinder interface has changed with new parameters in
the methods. Simple enough.

* The UrlReferrer property on IRailsEngineContext has disappeared.
UnderlyingContext.Request.UrlReferrer is the presumed replacement.

* Controller's ObtainDefaultLayoutName() now returns a string[]
instead of a string. This seems odd to me.

* SmartDispatcherController's CreateAbsoluteRailsUrl() is no longer
available. We can work around.

* ControllerFactory's CreateController() method no longer has an
overload that accepts an UrlInfo object.

* PaginationHelper's CreatePagination() overloads seem to now require
an IEngineContext and is now generic. A simple enough change.

* In ViewComponent, the RailsContext property has been renamed to
EngineContext. Does a prettier name really justify a breaking change?

* The addition of the Validator namespace causes a nasty namespace
collision. But is cosmetic.

* The Logger and Context properties on the Controller class are no
longer public, which makes a few logging handlers break.

* The PropertyBag property is no longer public on controllers. How can
my BeforeAction filters now inject data into the controller? Define my
own interface for this? (Think of an [AddCartToPropertyBag] or an
[AddMenuToPropertyBag] attribute that decorates a class.)

* The protected virtual InternalSend() method on
SmartDispatcherController no longer exists. We had been using a lock
here to work around NVELOCITY-12, a severe threading problem in RC2,
and a few other sundry logging statements happen here. I assume the
new method to override is InvokeMethod()?

... I gave up at this point, seeing as it will take a lot of revisions
to get the code to even compile.

So the question, and point of this post, is: Has anyone ever
realistically upgraded from RC2? We certainly are pioneering a new
usage of the phrase "release candidate." There seems to be no
migration path here.

At this point, I reckon that it will be easier to just keep this site
on RC2 until its end of life, unless anyone has some insightful
recommendations. I suppose I could always do "baby upgrades" to
previous trunk points in history where there are fewer breaking
changes to deal with all at once, but it doesn't seem worth the
effort. It seems it'd be nearly as difficult to jump ship to a
completely different framework.

RC2, at least, has been a great product and I'm very thankful to the
community for it, but I must admit that all of these changes has me
concerned about the direction and health of the project. Any insight
that can be provided would be appreciated, and thanks for listening to
my rant! =)

V/R,
Nicholas Piasecki

Flominator

unread,
Feb 10, 2009, 2:56:49 AM2/10/09
to Castle Project Users
Hi Nicholas,

I've upgraded my current case study to trunk some weeks ago. Worked
quite well when following
http://codeprairie.net/blogs/chrisortman/archive/2008/01/09/catching-up-with-castle-trunk-4710.aspx

Best regards,

Flo

Ben Lovell

unread,
Feb 10, 2009, 4:36:27 AM2/10/09
to castle-pro...@googlegroups.com
OK so they documentation isn't fantastic but you're not going to get much sympathy here if you've just dropped in the new dlls, F5'd your solution and then compiled a three page whine when it doesn't work. A small amount of research/google would have led you to a good few blogs detailing the breaking changes.

Thank you for you concern on the health of the project. I would suggest you check the jira/donjon, pick up some issues and submit some patches.

/rant over/

I've upgraded several projects (some pretty damn large indeed) successfully. It is more than worth the effort of spending just a few hours bringing your project up to date since it will be time well-spent in transitioning to new releases in the future.

Thanks,
Ben

Nicholas Piasecki

unread,
Feb 10, 2009, 7:36:45 PM2/10/09
to Castle Project Users
Thanks for the advice, y'all. We will stay on RC2 for now and backport
the required fixes.

I didn't mean to be inflammatory or to invoke knee-jerk reactions, and
if that was the result, then I apologize. To be clear, MonoRail has
been incredible for us and particularly at a time when Microsoft
offered no alternate solution. When I'm talking about the health of
the project, however, I'm not talking about bugs or submitting
patches. There are plenty of MonoRail users and enthusiastic MonoRail
developers submitting patches, but it is the patches themselves that
are the problem. Developers all scratching their own itches and
submitting their own features and improvements each week in ways that
do not always consider backwards compatibility greatly reduces the
accessibility and utility of those fixes.

Let's take the NVELOCITY-12 issue as an example. Once this severe
threading problem was discovered in our codebase, developers worked
around it by adding a static lock in the Controller's InternalSend()
method, along with a scary comment that indicated to never alter that
code without validating that the issue was fixed by performing the
load balancing stress tests. It is not performant and not ideal, but
it is safe. And so it sat there for some time. Now let's suppose that
after many moons of furious feature-adding, and the dust has settled
on this project, I want to go back and clean up this code wart.

How do I get this bugfix? I could immediately try downloading the RC3
binaries and update the whole framework, but this breaks an
unexpectedly large number of bits of unrelated code in our project. I
could download the latest NVelocity DLL from RC3, the next public
release candidate where the issue was fixed, but then the
Castle.MonoRail.Framework.Views.NVelocity DLL complains about not
finding the expected version, which is indeed only to be expected. In
a typical release candidate scenario, where few changes are expected,
I could grab the two new versions of just these two DLLs, and since
they are loaded from configuration, expect things to just work. But
there were in fact many changes to the *interfaces* that the views DLL
itself uses, making the whole shebang dependent on changes that
occurred later in the trunk.

Now I have two choices. (1) I could make massive code changes to bring
everything up to the trunk level to get this fix. Even with unit
tests, this move simply does not make sense--the bulk of RC2 and its
feature set are not broken, just this one bit. It's been running well
and serving thousands of requests for two years now. And post-RC2, the
new routing system, the new extensibility points, the easier unit
testing: these are all neat things, but I don't need them right now to
finish this task with minimal impact. Software is not a business
advantage for this company and mainly exists to "make things work" and
"keep them working." To that end, (2) I could also use the new
NVelocity DLL and recompile the RC2 views DLL against it. I'll take
this option, but it's not ideal because I'm now out of sync with *any*
public release candidate and am effectively maintaining my own
miniature branch of the NVelocity view template implementation. One
more thing to take under my wing.

And this is what I was trying to state about the health of the
project: not in terms of bugginess, lack of patches, or developer
enthusiasm, but in terms of release management and source control.
NVELOCITY-12 is exactly the type of blocker issue that would be fixed
in a release candidate. MR-ISSUE-180, where routing broke under the
Turkish locale, is another good example of a release candidate change.
Adding features or breaking interfaces, however, is something that
would happen on a completely separate code branch, say, MonoRail 1.5,
with the major applicable bug fixes backported down. Doing everything--
bugs and features--on the trunk and only the trunk makes cherry
picking the really important bug fixes difficult. And though I have
seen this issue discussed before on both hammett's blog and in the
developer discussion list, after keeping an eye on the commit logs
over the past year, I don't see the sea change happening anytime soon.
I'm not a configuration management expert, but I do recognize what
will cause maintenance issues down the line, and my nailing a list of
code breakages and grievances to the users forum is my humble of way
of making this opinion known. Take it with a grain of salt, leave it
as you please.

Thanks for working on MonoRail, and thanks for listening! I appreciate
every MonoRail developer and user and only hope to strengthen the
community with my feedback.

V/R,
Nicholas Piasecki

Ken Egozi

unread,
Feb 11, 2009, 1:16:14 AM2/11/09
to castle-pro...@googlegroups.com
Hi Nicholas.
I'll try to address your problems:

* MonoRailHttpHandler and CurrentContext:
The monorail's Context class has been broken down into the EngineContext and the ControllerContext. you can get a hold of these using MonoRailHttpHandlerFactory.CurrentEngineContext, and same.CurrentControllerContext

IRailsEngineContext, ExecuteEnum/When etc:
The public API needed some cleanup. however it is a simpe search-and-replace fix

IFilter and IControllerContext:
see previous paragraph

IsPreConditionSatisified() on WizardStepBase
It was needed to be exposed. as you have said, search-and-replace fixes it

Redirect methods:
a. Now they are partd of IRedirectSupport interface.
b. Redirect is now for redirecting to actions. The overload taking Url is gone in favour of the new RedirectToUrl. This makes the intention clearer.

Initialize on WizardStepBase:
What is your need exactly?

IWizardController returning interfaces:
most of the framework went into the direction of coding to interfaces.  I believe it's a very good move, and one of the things where MR beats ASP.NET MVC in.

Controller.Initialize() gone public
discussed

SDC.SelectMethod():, IParameterBinder
more features => code changes.  easy to fix your codebase

UrlReferrer
is relevant to the request, not the context, so it moved.

LayoutName being string[]
you can have nested layouts now.  it's actually very useful

SmartDispatcherController.CreateAbsoluteRailsUrl():
Truth? never seen this method ...  what was it doing?

ControllerFactory/CreateController() and no UrlInfo:
is that a problem? please present a use case

PaginationHelper's.CreatePagination() :
Things require context.

RailsContext / EngineContext:
That was actually a blessed change. As I said, the is a distinction now between different types of contexts


The Logger and Context properties on the Controller class are no longer public
The context can (and should) be obtained from the object using it, or as a method parameter, and not necessarily through the controller.

PropertyBag
can be accessed by the current IControllerContext

InternalSend and NV locking issue
Hopefully this bug is fixed now so you won't need that

Anyway, if you find yourself poking around deep in the source code and fixing problems for your own application, (like hacking InternalSend, Controller factories, etc.) then I think it'd be better for you to bring these issues onto this group, or better yet, the developers group, right when you find the problems.
a. people might have already solved your problems
b. people might be able to enjoy your solutions
c. if a valid solution enters the codebase soon enough, the breaking changes you'd have won't be there anymore

Reply all
Reply to author
Forward
0 new messages