text:
Large scale distributed consensus approaches: Computing with a hundred node cluster
I'm using 100/99 node cluster as the example, but the discussion also apply for smaller clusters (dozens of nodes) and bigger clusters (hundreds or thousands). Pretty much the only reason that you want to go with clusters of that size is that you want to scale out your processing in some manner. I've already discussed why a hundred node cluster isn't a good option for safety reasons.
Consensus algorithm create a single consensus in the entire cluster, usually about an order set of operations that are fed to a state machine. The easiest such example would be a dictionary. But it make no sense to have a single dictionary spread across hundred nodes. Why would you need to do that? How would it give you the ability to make full use of all of the power of all those nodes?
Usually nodes are used for either computing or storage purposes. Computing is much easier, so let us take that as a good example. A route calculating system, need to do a lot of computations on a relatively small amount of information (the map data). Whenever there is a change in the map (route blocked, new road open, etc), it needs to send the information to all the servers, and make sure that it isn't lost.
Since calculating routes is expensive (we'll ignore the options for optimizations and caching for now), we want to scale it to many nodes. And since the source data is relatively small, each node can have a full copy of the data. Under this scenario, the actual problem we have to solve is how to ensure that once we save something to the cluster, it is propagated to the entire cluster.
The obvious way to do this is with a hierarchy:
Basically, the big icons are the top cluster, each of which is responsible for updating a set of secondary servers, which is then responsible for updating the tertiary servers.
To be perfectly honest, this looks nice, and even reasonable, but it is going to cause a lot of issues. Sure, the top cluster is resilient to failures, but relying on a node to be up to notify other nodes isn't so smart. If one of the nodes in the top cluster goes down, then we have about 20% of our cluster that didn't get the notice, which kind of sucks.
A better approach would be to go with a management system and a gossip background:
In other words, the actual decisions are down by the big guys (literally, in this picture). This is a standard consensus cluster (Paxos, Raft, etc). Once a decision has been made by the cluster, we need to send it to the rest of the nodes in the system. We can do that either by just sending the messages to all the nodes, or by selecting a few nodes and have them send the messages to their peers. The protocol for that is something like: "What is the like command id you have? Here is what I have after that." Assuming that each processing node is connected to a few other servers, that means that we can send the information very quickly to the entire cluster. And even if there are errors, the gossiping server will correct it (note that there is an absolute order of the commands, ensured by the consensus cluster, so there isn't an issue about agreeing to this, just distributing the data).
Usually the gossip topology follows the actual physical distribution. So the consensus cluster will notify a couple of servers on each rack, and let the servers in the rack gossip among themselves about the new value.
This means that once we send a command to the cluster, the consensus would agree on that, then we would distribute it to the rest of the nodes. There is a gap between the consensus confirming it and the actual distributing to all the nodes, but that is expected in any distributed system. If it is important to sync this on a synchronized basis across the entire cluster, the command is usually time activated (which require clock sync, but that is something that we can blame on the ops team, so we don't care ).
With this system, we can have an eventually consistent set of data across the entire cluster, and we are happy.
Of course, this is something that is only relevant for compute clusters, the kind of things were you compute a result, return it to the client and that is about it. There are other types of clusters, but I'll talk about them in my next post.
Live playground for RavenDB 3.0
We are getting to the part where we are out of things to do, so we setup a live instance of RavenDB 3.0 and opened it up for the world to play with.
It is available here: http://live-test.ravendb.net
Disclaimer - It may go down at any moment, data will routinely be wiped but is public and can be copied and used for other users. This is strictly for playing around with it, nothing more.
Give it a shot, see all the new cool stuff.
Large scale distributed consensus approaches: Calculating a way out
The question cross my desk, and it was interesting enough that I felt it deserves a post. The underlying scenario is this. We have distributed consensus protocols that are built to make sure that we can properly arrive at a decision and have the entire cluster follow it, regardless of failure. Those are things like Paxos or Raft. The problem is that those protocols are all aimed at relatively small number of nodes. Typically 3 – 5. What happens if we need to manage a large number of machines?
Let us assume that we have a cluster of 99 machines. What would happen under this scenario? Well, all consensus algorithm works on top of the notion of a quorum. That at least (N/2+1) machines have the same data. For a 3 nodes cluster, that means that any decision that is on 2 machines is committed, and for a 5 nodes cluster, it means that any decision that is on 3 machines is committed. What about 99 nodes? Well, a decision would have to be on 50 machines to be committed.
That means making 196 requests (98 x 2) (once for the command, then for the confirmation) for each command. That… is a lot of requests. And I'm not sure that I want to see what it would look like in term of perf. So just scaling things out in this manner is out.
In fact, this is also pretty strange thing to do. The notion of distributed consensus is that you will reach agreement on a state machine. The easiest way to think about it is that you reach agreement on a set of values among all nodes. But why are you sharing those values among so many nodes? It isn't for safety, that is for sure.
Assuming that we have a cluster of 5 nodes, with each node having 99% availability (which translates to about 3.5 days of downtime per year). The availability of all nodes in the cluster is 95%, or about 18 days a year.
But we don't need them to all be up. We just need any three of them to be up. That means that the math is going to be much nicer for us (see here for an actual discussion of the math).
In other words, here are the availability numbers if each node has a 99% availability:
|Number of nodes
|~ 2.5 hours per year
|99.999% (5 nines)
|~ 5 minutes per year
|99.9999% (6 nines)
|~ 12 seconds per year
Note that all of this is based around each node having about 3.5 days of downtime per year. If we can have availability of 99.9% (or about 9 hours a year), the availability story is:
|Number of nodes
|~ 2 minutes a year
|99.999999% ( 8 nines )
|~ 30 seconds per year
So in rough terms, we can say that going to 99 node cluster isn't a good idea. It is quite costly in terms of the number of operation require to ensure a commit, and from a safety perspective, you can get the same safety level at the drastically lower cost.
But there is now another question, what would we actually want to do with a 99 node cluster*? I'll talk about this in my next post.
A hundred node cluster only make sense if you have machines with about 80% availability. In other words, they are down for 2.5 months every year. I don't think that this is a scenario worth discussing.
Is the library open or not?
An interesting challenge came across my desk. Let us assume that we have a set of libraries, which looks like this:
{ "Name": "The Geek Hangout", "OpeningHours": { "Sunday": [ { "From": "08:00", "To": "13:00" }, { "From": "16:00", "To": "19:00" } ], "Monday": [ { "From": "09:00", "To": "18:00" }, { "From": "22:00", "To": "23:59" } ], "Tuesday": [ { "From": "00:00", "To": "04:00" }, { "From": "11:00", "To": "18:00" } ] } }
{ "Name": "Beer & Books", "OpeningHours": { "Sunday": [ { "From": "16:00", "To": "23:59" } ], "Monday": [ { "From": "00:00", "To": "02:00" }, { "From": "10:00", "To": "22:00" } ], "Tuesday": [ { "From": "10:00", "To": "22:00" } ] } }
I only included three days, to make it shorter, but you get the points. You can also see that there are times that the opening hours go through a day.
Now, the question we need to answer is: "find me an open library now".
How can we answer such a question? If we were using SQL, it would be something like this:
select * from Libraries l where Id in ( select Library Id OpeningHours oh where oh.Day = dayofweek(now()) AND oh.From >= now() AND oh.To < now() )
I'll leave the performance of such a query to your imagination, but the key point is that we cannot actually express such a computation in RavenDB. We can do range queries, but in this case, it is the current time that we compare to the range of values. So how do we answer such a query?
As usual, but not trying to answer the same thing at all. Here is my index:
The result of this is an index entry per day, and in each index entry, we have outputted the half hours that this library is open. So if we want to check for libraries that are open on Sunday at 4:30 PM, all we have to do is issue the following query:
The power of dynamic fields and index time computation means that this is an easy query to make, and even more importantly, this is something that we can answer very efficiently.
RavenDB 3.0 & Subscription Licenses
We were asked this a few times, so I think it is worth clarifying.
If you have a subscription license to RavenDB, you have automatic access to all versions of RavenDB for as long as your subscription is current. That means that if you purchase a RavenDB 2.x subscription, your license allows you to use RavenDB 3.0 without any issues.
Note that this doesn't include using RavenFS, which will require an updated license.
If you purhcased RavenDB using the one time code, you'll need to purchase a new license for RavenDB 3.0.
Fixing a production issue
So we had a problem in our production environment. It showed up like this.
The first thing that I did was log into our production server, and look at the logs for errors. This is part of the new operational features that we have, and it was a great time to try it under real world conditions:
This gave me a subscription to the log, which gave me the exact error in question:
From there, I went to look at the exact line of code causing the problem:
Can you see the issue?
We create a dictionary that was case sensitive, and they used that to create a dictionary that was case insensitive. The actual fix was adding the ignore case comparer to the group by clause, and then pushing to production.
The RavenDB new website (and the beta discount)!
I'm currently with some of our team in the Oredev conference. So if you are here, seek us out.
In other good news, the new website for RavenDB is now up, and that means that we are no longer selling RavenDB 2.x. We are now selling RavenDB 3.0 only*!
With this, the last hurdle of releasing RavenDB 3.0 is pretty much out the door, we'll probably wait until we are back from Oredev and recover a bit, but we are on track for a stable release of RavenDB 3.0 next week or the one just after.
In the meantime, go ahead and look at the new website.
* A RavenDB 3.0 license can work for 2.5, though.
Finding the "best" book scenario
This started out as a customer engagement, but it was interesting to see how we solved it.
The problem is searching for books. Let us take the following books as good example:
We have users that want to have recommendations for books in specific topics, and authors can pay us to promote their books. You can see how it looks like above.
Now, the rules we want to follow for sorting the results are fairly simple. Find all the matching books, and sort them so:
- The user has searched for a book primary tag, and the author paid to promote that tag, show first.
- The user has searched for a book secondary tag, and the author paid to promote that tag, show second.
- The user has searched for a book primary tag, and the author didn't paid to promote that tag, show third.
- The user has searched for a book secondary tag, and the author didn't paid to promote that tag, show forth.
Actually trying to specify the sort order according to this tend to be quite hard to do, as it turns out, but we can take advantage of boosting to get what we want.
We define the following index:
from book in docs.Books select new { PaidPrimaryTag = book.Tags.Where(x=>x.Primary && x.Paid).Select(x=>x.Name), PaidSecondaryTag = book.Tags.Where(x=>x.Primary == false && x.Paid).Select(x=>x.Name), PrimaryTag = book.Tags.Where(x=>x.Primary).Select(x=>x.Name), SecondaryTag = book.Tags.Where(x=>x.Primary == false).Select(x=>x.Name), }
And now we want to do a few searches: First for NoSQL and then RavenDB.
The actual query we issue is:
And as you can see, books/3 is shown first, because the author paid for higher ranking. What about when we do that with RavenDB?
We have books/3, as before, but books/2 is higher ranked than books/1. Why is that? Because books/2 paid to have a higher ranking on a secondary tag, and it is more important than even a primary tag match according to our query.
This is quite elegant, and it also allows us to take into account relevancy in the search as well.
Bug tracking, when your grandparent isn't in your family tree
We got a failing test because of some changes we made in RavenDB, and the underlying reason ended up being this code:
The problem was that the type that I was expecting did inherit from the right stuff. See this:
So something here is very wrong. I tracked this until I got to:
return RuntimeTypeHandle.CanCastTo(fromType, this);
And there is stopped. I work around this issue by using IsSubclassOf, instead of IsAssignableFrom.
The problem with IsAssignableFrom is that it is a confusing method. The parent is supposed to be the target, and the type you check is the parameter, but it is very easy to forget that and get confused. This worked for 99% of cases, because the single assembly we usually use also contained the RavenBaseApiController (which obviously can be assigned to itself), so that looked like it worked. IsSubclassOf is much nicer, but you need to understand that this won't work for interfaces, or check direct equality. In this case, this was exactly what I needed, so that worked.
Corvus: Manage your databases from your Android
Corvus is an open source mobile client for the RavenDB document database.
It is available on the Google Store now.
Modeling exercise: The grocery store's checkout model process approach
I posted about the grocery store checkout process exercise before. Now I want to see if I can do a short outline on how I would handle this.
The key aspect from my perspective is that we need to separate the notion of the data we have and the processing of the data. That means that we are going to have the following model:
public class ShoppingCart { public List<ProductInShoppingCart> Products {get;set;} public List<Discount> Discounts { get;set; } } public class ProductInShoppingCart { public string ProductId; public Discount Discount; }
Note that we explicitly do not have a quantity field here. If we purchase 6 bottles of milk, that would appear three times in the cart. Why is that?
Let us assume that we have a sale for 2 bottles of milk for 20% discount or a 3 +1 bottles of milk offer. Consider the kind of code you would have to write in the offer code:
- Find all products that have this offer and have 4 items without discount.
- Add the discount to those products.
- After searching for products without discount, need to search for products with a discount, but that we can apply this to and get a better option.
In this case, we start by doing:
- Add bottle of milk
- Add bottle of milk – 2 for 20% discount is triggered.
- Add bottle of milk
- Add bottle of milk – 3+1 offer is triggered, removing the previous discount.
Because this is likely going to be complex, I'm going to be writing this once. A set of offers and the kind of rules that we want. Then we will give the users the ability to define those rules.
Note that we keep the raw data (products) and the transformations (discounts) separate, so we can always reapply everything without losing any data.
Career planning: Mine
I got some really good questions about my career. Which caused me to reflect back and snort at my own attempts to make a sense of what happened.
Here is a rough timeline:
- 1999 – Start of actually considering myself to be a professional developer. This is actually the start of a great one year course I took to learn C++, right out of high school.
- 2001 – Joined the army, was sent to the Military Police, and spent 4 years in prison. Roles ranged from a prison guard, XO of big prison, teacher in officer training course and concluded with about a year as a small prison commander.
- 2004 – Opened my blogged and started writing about the kind of stuff that I was doing, first version of Rhino Mocks.
- 2005 – Joined the Castle Comitter's team, Left the army, joined We!, worked as a consultant.
- 2006 – My first international conference – DevTeach.
- 2008 – Left We!, started working as an independent consultant.
- 2009 – NHibernate Profiler beta release.
- 2010 – DSLs in Book book is published, Entity Framework Profiler, Linq to SQL Profiler, RavenDB.
- 2011 – Hiring of first full employee.
- 2014 – Writing this blog post.
A lot of my history doesn't make sense without a deeper understanding. In the army, there was a long time in which I wasn't actually able to do anything with computers. That meant that on vacations, I would do stuff voraciously. At that time, I already read a lot of university level books (dinosaurs book, Tanenbaum's book, TCP/IP, DDD book and a lot of other stuff like that). At some point, I got an actual office and had some free time, so I could play with things. I wrote code, a lot. Nothing that was actually very interesting. It was anything from mouse tracking software (that I never actually used) to writing custom application to track medical data for inmates. Mostly I played around and learned how to do stuff.
When I got to be a prison commander, I also got myself a laptop, and start doing more serious stuff. I wasn't able to afford any professional software, so it was mostly Open Source work. I started working on NHibernate Query Analzyer, just to see what I can do about it. That thought me a lot about reflection and NHibernate itself. I then got frustrated with the state of mocking tools in the .NET framework, and I decided to write my own. Around that time, I also started to blog.
What eventually became Rhino Mocks was a pretty big thing. Still one of the best pieces of software that I have written, it required that I'll have a deep understanding of a lot of things. From IL generation to how classes are composed by the runtime to AppDomains to pretty much everything.
Looking back, Rhino Mocks was pretty huge in terms of pushing my career. It was very widely used, and it got me a lot of attention. After that, I was using NHibernate and talking about that a lot, so I got a lot of reputation points in that arena as well. But the first thing that I did after starting as an independent consultant was to actually work on SvnBridge. A component that would allow an SVN client to talk to a Team Foundation Server. That was something that I had very little experience with, but I think that I did a pretty good job there.
Following that, I mostly did consulting and training on NHibernate. I was pretty busy. So busy that at some point I actually have a six week business trip that took me to five countries and three continents. I came back home and didn't leave my bed for about a week. For two weeks following that, I would feel physically ill if I sat in front of the computer for more than a few minutes.
That was a pretty big wakeup call for me. I knew that I had to do something about it. That is when I actually sat down and thought about what I wanted to do. I knew that I wanted to stay in development, and that I couldn't continue being a road warrior without burning out again. I decided that my route would be to continue to do consulting, but on a much reduced frequency, and to start focusing on creating products. Stuff that I could work on while at home, and hopefully get paid for. That is how the NHibernate Profiler was born.
From there, it was a matter of working more on that and continuing to other areas, such as Entity Framework, Linq to SQL, etc. RavenDB came because I got tired of fixing the same old issues over and over again, even with the profilers to help me. And that actually had a business plan, we were going to invest so much money and time to get it out, and it far exceeded our expectations.
Looking back, there were several points that were of great influence. Writing my blog. Writing Rhinos Mocks, joining open source projects such as Boo or Castle. Working and blogging with NHibernate. Going to conferences and speaking there. All of those gave me a lot of experience and got me out there, building reputation and getting to know people.
That was very helpful down the road, when I was looking for consultancy jobs, or doing training. Or when it came the time to actually market our software.
In terms of the future, Hibernating Rhinos is growing at a modest rate. Which is the goal. I don't want to double every six months, that is very disturbing to one's peace of mind. I would much rather have a slow & steady approach. We are working on cool software, we are going home early and for the most part, there isn't a "sky is falling" culture. The idea is that this is going to be a place that you can spend a decade or four in. I'll get back to you on that when I retire.
Career planning: Disaster recovery
One of the more important things that you have to remember is that you should always be ready for failure. As developers, we are used to thinking about stuff like that in our code, but this is true for real life as well.
I'm going to leave aside things like personal disasters for this post (things like car accidents, getting seriously sick, etc), because there are some ways to mitigate those (insurance, family, etc) and they really isn't anything special in development to say about those. Instead, I want to talk about professional disasters.
Those can be things like:
- Company closing (nicely or otherwise).
- Getting fired.
- Product going under.
- Product doing badly.
- Reputation smear.
- High profile failure.
Let me try take them in turn. The easiest one to handle is probably a company closing down, there is very little blame attached here, so there shouldn't be an issue of having a new job. This is also the time to consider if you want to move tracks to be an independent or entrepreneur. Getting fired is a bit harder, but assuming that you weren't fired for cause (such as negligence of criminal behavior), the old "everyone is downsizing" is going to work.
Even in a so-so economy, there is still a lot of jobs out there for software developers, but getting a good one might require you to polish your skills, and getting good idea of what is marketable today. Note that there is a big difference between what is popular and what is marketable (as in, will land you a job). Node.JS seems to be the buzzword of the day, but knowing Java very well is probably a much better path for quick employment.
This comes back to what kind of approach you want to take. For now, I'm going to assume that the fallback position for a good developer is to get hired in some fashion, it can be a short term contract, or just be gainfully employed writing software. This is important when we consider the other things that can happen, those are the kind of disasters that strike when you are more than just an employee. If you are entrepreneur and your product is just loosing too much money, for example, what is your next path?
The easy thing is when you know that you can't go on. Maybe a competitor is pricing you out of the market, or the bank is closing the credit line or you can't get more client or any of a hundred reasons. You are done, and you are well aware of that. A much harder issue is when you are just doing badly. So you do make sales, but not enough to cover expenses, or just getting by. Not enough to bankrupt you immediately, but you can see it happening. Unless something changes… So you have the option of pulling the cord or trying to get it to work, with the chance of going to actual failure.
For a startup, you usually don't have to deal with those details, but you might just show up and the company is closing down. In those cases, there is usually not much that can be done by you (unless you are the founder, in which case, there is a wealth of information on that issue out there).
The last issue that you need to take into account is how to deal with reputation damage or a high profile failure. That depend on what the actual issue is. If it is a high profile arrest for doing coke, it might be hard to get / retain clients. If it is a big failure that cost a customer a lot of money, you might be dealing with legal consequences as well as the actual damage with other customers.
We can simplify how we look at this if we treat it all as the same thing, just a basic setback to zero (or negative). The issue is how to recover and move on. At this point, the issue is what sort of future you want? Setbacks like that are a great reason to do some thinking about where you want to go and what you want to actually do.
The conservative choice would be to find a job as a full time developer of some kind, since that at least give you a steady paycheck for the duration. More complex can be the decision to do contracting, either on a short term (at worst you can be a Word Press consultant and install that to people) or longer term projects (which require you to actually sale yourself). Hopefully you won't be doing someone's else homework, at least not for long.
Note that actually being able to recover from a disaster properly require prior planning. Do you have resources to survive a duration with no money? Can you handle (mentally) being out of work? Are you running on the razor's edge of a single disruption in money flow causes an utter collapse. If that is the case, your disaster planning is going to focus on just getting reserves to handle any hiccups, versus actually managing an actual disaster.
Oh, and of course, you need to consider the cost of disaster planning. It is all very well to build a bunker to survive atomic war and the zombie rampage, but it isn't that good if it also bankrupt you on its own.
The general recommendation is to stay current, so it would be easier to hire you, and have some idea about what to do if you wake up one day, and for whatever reason, showing up for work is not going to happen.
Career planning: What is your path?
I got a lot of really great answers about my "Where do old developers go?", I'm feeling much better about this now .
Now let turn this question around, instead of asking what is going on in the industry, let's check what is going on with you. In particular, do you have a career plan at all?
An easy way to check that is asking: "What are you going to do in 3 years, in 7 years and in 20 years from now?"
Of course, best laid plans of mice and men will often go awry, plans for the futures are written in sand on a stormy beach and other stuff like this. Any future planning has to include the caveats that they are just plans, with reality and life getting in the way.
For lawyers*, the career path might be: Trainee, associate, senior associate, junior partner, partner, named partner. (* This is based solely on seeing some legal TV shows, not actual knowledge.) Most lawyers don't actually become named partners, obviously, but that is what you are planning for.
As discussed in the previous post, a lot of developers move to management positions at some point in their careers, mostly because salaries and benefits tend to flat line after about ten years or so for most people in the development track. Others decide that going independent and becoming consultants or contractors is a better way to increase their income. Another path is to rise in the technical track in a company that recognize technical excellence, those are usually pure tech companies, it is rare to have such positions in non technical companies. Yet another track that seems to be available is the architect route, this one is available in non tech companies, especially big ones. You have the startup route, and the Get Rich Burning Your Twenties mode, but that is a high risk / high reward, and people who think about career planning tend to avoid such things unless carefully considered.
It is advisable to actually consider those options, try to decide what options you'll want to have available for you in the next 5 – 15 years, and take steps accordingly. For example, if you want to go in the management track, you'll want to work on thinks like people's skill, be able to fluently converse with the business in their own terms and learn to play golf. You'll want to try to have leadership positions from a relatively early start, so team lead is a stepping stone you'll want to get to, for example. There is a lot of material on this path, so I'm not going to cover this in details.
If you want to go with the Technical Expert mode, that means that you probably need to grow a beard (there is nothing like stroking a beard in quite contemplation to impress people). More seriously, you'll want to get a deep level of knowledge in several fields, preferably ones that you can tie together into a cohesive package. For example, networks expert would be able to understand how TCP/IP work and be able to actually make use of that when optimize an HTML5 app. Crucial at this point is also the ability to actually transfer that knowledge to other people. If you are working within a company, that increase the overall value you have, but a lot of the time, technical experts would be consultants. Focusing on a relatively narrow field gives you a lot more value, but narrow your utility. Remember that updating your knowledge is very important. But the good news is that if you have a good grasp of basics, you can get to grips with new technology very easily.
The old timer mode fits people who work in big companies and who believe that they can carve a niche in that company based on their knowledge of the company's business and how things actually work. This isn't necessarily the one year experience, repeated 20 times, although in many cases, that seems to be what happens. Instead, it is a steady job with reasonable hours, and you know the business well enough and the environment in which you are working with, that you can just get things done, without a lot of fussing around. Change is hard, however, because those places tend to be very conservative. Then again, you can do new systems in whatever technology you want, at a certain point (you tend to become the owner of certain systems, you've been around longer than the people who are actually using the system). That does carry a risk, however. You can be fired for whatever reason (merger, downsizing, etc) and you'll have hard time finding equivalent position.
The entrepreneur mode is for people who want to build something. That can be a tool or a platform, and they create a business selling that. A lot of the time, it involve a lot of technical work, but there is a huge amount of stuff that needs to be done that is non technical. Marketing and sales, insurance and taxes, hiring people, etc. The good thing about this is that you usually don't have to have a very big investment in your product before you can start selling it. We are talking about roughly 3 – 6 months for most things, for 1 – 3 people. That isn't a big leap, and in many cases, you can handle this by eating some savings, or moonlighting. Note that this can completely swallow your life, but you are your own boss, and there is a great deal of satisfaction around building a product around your vision. Be aware that you need to have contingency plans around for failure and success. If your product become successful, you need to make sure that you can handle the load (hire more people, train them, etc).
The startup mode is very different than the entrepreneur mode. In startup, you are focused on getting investments, and the scope is usually much bigger. There is less of a risk financially (you usually have investors for that), but there is a much higher risk of failure, and there is usually a culture that consider throwing yourself on hand grenade advisable. The idea is that you are going to burn yourself on both ends for two to four years, and in return, you'll have enough money to maybe stop working altogether. I consider this foolish, given the success rates, but there are a lot of people who consider that to be the only way worth doing. The benefits usually include a nice environment, both physically and professionally, but it comes with the expectation that you'll stay there for so many hours, it is your second home.
There are other modes and career paths, but now I've to return to my job .
Modeling exercise: The grocery store's checkout model
I went to the super market yesterday, and I forgot to get out of work mode, so here is this posts. The grocery store checkout model exercise deals with the following scenario. You have a customer that is scanning products in a self checkout lane, and you need to process the order.
In terms of external environment, you have:
- ProductScanned ( ProductId: string ) event
- Complete Order command
- Products ( Product Id –> Name, Price ) dataset
So far, this is easy, however, you also need to take into account:
- Sales (1+1, 2+1, 5% off for store brands, 10% off for store brands for loyalty card holders).
- Purchase of items by weight (apples, bananas, etc).
- Per customer discount for 5 items.
- Rules such as alcohol can only be purchased after store clerk authorization.
- Purchase limits (can only purchase up to 6 items of the same type, except for specific common products)
The nice thing about such an exercise is that it forces you to see how many things you have to juggle for such a seemingly simple scenario.
A result of this would be to see how you would handle relatively complex rules. Given the number of rules we already have, it should be obvious that there are going to be more, and that they are going to be changing on a fairly frequent basis. A better model would be to actually do this over time. So you start with just getting the first part, then you start streaming the other requirements, but what you actually see is the changes in the code over time. So each new requirement causes you to make modifications and accommodate the new behavior.
The end result might be a Git repository that allows you to see the full approach that was used and how it changed over time. Ideally, you should see a lot of churn in the beginning, but then you'll have a lot less work to do as your architecture settles down.
Career planning: Where do old devs go to?
We are pretty much always looking for new people, what is holding us back from expanding even more rapidly is the time that it takes to get to grips with our codebases and what we do here. But that also means that we usually have at least one outstanding job offer available, because it takes a long time to fill it. But that isn't the topic for this post.
I started programming in school, I was around 14 / 15 at the time, and I picked up a copy of VB 3.0 and did some fairly unimpressive stuff with it. I count my time as a professional since around 1999 or so. That is the time when I started actually dedicating myself to learning programming as something beyond a hobby. That was 15 years ago.
When we started doing a lot of interviews, I noticed that we had the following pattern regarding developers' availabilities:
That sort of made sense, some people got into software development for the money and left because it didn't interest them. From the history of Hibernating Rhinos, one of our developers left and is now co-owner in a restaurant, another is a salesman for lasers and other lab stuff.
However, what doesn't make sense is the ratio that I'm seeing. Where are the people who have been doing software development for decades?
Out of the hundreds of CVs that I have seen, there has been less than 10 that had people over the age of 40. I don't recall anyone over the age of 50. Note that I'm somewhat biased to hire people with longer experience, because that often means that they don't need to learn what goes under the hood, they already know.
In fact, looking at the salary tables, there actually isn't a level of higher than 5 years. After that, you have a team leader position, and then you move into middle management, and then you are basically gone as a developer, I'm guessing.
What is the career path you have as a developer? And note that I'm explicitly throwing out management positions. It seems that those are very rare in our industry.
Microsoft has the notion of Distinguished Engineer and Technical Fellow, for people who actually have decades of experience. In my head, I have this image of a SWAT team that you throw at the hard problems .
Outside of very big companies, those seem to be very rare. And that is kind of sad.
In Hibernating Rhinos, we plan to actually have those kind of long career paths, but you'll need to ask me in 10 – 20 years how that turned out to be.
The holidays, plans & what is next
So, we are done with the holidays here. The last month was basically very little work, because a lot of our people were out for the holidays.
Internally, we are gearing up to finish the website for RavenDB 3.0, while another part of the team is focused on stability and performance. We just hired another new guy, and he is going to be working pretty much on distribution from now on. I'll report more on that in a few weeks.
Looking at the blog, I've mostly been talking about RavenDB, and I want to do a small shift and talk about other topics, so I'm declaring the next two weeks to be RavenDB free weeks. I'm going to continue to blog regularly, of course, but I'm going to be talking about other topics for a change.
Don't worry, we haven't stopped working on RavenDB, it is just that it is pretty boring to hear about things like test clusters, or how we work on issues from the people trying out the RC builds.
Release preps, and my mobile cluster
I just took this picture on my desk. This is a set of machines running a whole set of tests for RavenDB 3.0. On the bottom right, you can see one of our new toys (more below).
This new toy is a NUC (i5, 16 GB, 180 GB SSD). We have a couple of those (and will likely purchase more).
They have a very small form factor, and they are pretty cool machines. We got a few of them so we can have easier time testing distributed systems that are really distributed.
It also has a very nice effect of actually being able to carry around a full cluster and "deploy" it in a few minutes.
Looking at nopCommerce
I'm preparing for a talk about using multiple databases in a single application, and I wanted to show how this looks like in a real application. I wanted to take a look at nopCommerce as the target application.
To be fair, I haven't really worked with enterprise applications in a while, but I found some interesting stuff there. Note that I'm not doing anything like a full review. My goal is to show the concept, not explore the full implications of nopCommerce. The code in questions is from commit 1286b4f8d4c0ed2a5d6441db7cbd5398821d32f2.
nopCommerce is using Entity Framework for accessing SQL Server, so it was a simple matter to install the Entity Framework Profiler and take a peek into what was going on there. I then did the simplest thing I could think of, and searched for gift in the site:
Here is what happened:
Now, there are 25 queries, and a total of 40KB of SQL executed. Here is one such query:
SELECT [Project4].[Id] AS [Id],
[Project4].[Name] AS [Name],
[Project4].[Description] AS [Description],
[Project4].[CategoryTemplateId] AS [CategoryTemplateId],
[Project4].[MetaKeywords] AS [MetaKeywords],
[Project4].[MetaDescription] AS [MetaDescription],
[Project4].[MetaTitle] AS [MetaTitle],
[Project4].[ParentCategoryId] AS [ParentCategoryId],
[Project4].[PictureId] AS [PictureId],
[Project4].[PageSize] AS [PageSize],
[Project4].[AllowCustomersToSelectPageSize] AS [AllowCustomersToSelectPageSize],
[Project4].[PageSizeOptions] AS [PageSizeOptions],
[Project4].[PriceRanges] AS [PriceRanges],
[Project4].[ShowOnHomePage] AS [ShowOnHomePage],
[Project4].[IncludeInTopMenu] AS [IncludeInTopMenu],
[Project4].[HasDiscountsApplied] AS [HasDiscountsApplied],
[Project4].[SubjectToAcl] AS [SubjectToAcl],
[Project4].[LimitedToStores] AS [LimitedToStores],
[Project4].[Published] AS [Published],
[Project4].[Deleted] AS [Deleted],
[Project4].[DisplayOrder] AS [DisplayOrder],
[Project4].[CreatedOnUtc] AS [CreatedOnUtc],
[Project4].[UpdatedOnUtc] AS [UpdatedOnUtc]
FROM (SELECT [Limit1].[Id] AS [Id],
[Limit1].[Name] AS [Name],
[Limit1].[Description] AS [Description],
[Limit1].[CategoryTemplateId] AS [CategoryTemplateId],
[Limit1].[MetaKeywords] AS [MetaKeywords],
[Limit1].[MetaDescription] AS [MetaDescription],
[Limit1].[MetaTitle] AS [MetaTitle],
[Limit1].[ParentCategoryId] AS [ParentCategoryId],
[Limit1].[PictureId] AS [PictureId],
[Limit1].[PageSize] AS [PageSize],
[Limit1].[AllowCustomersToSelectPageSize] AS [AllowCustomersToSelectPageSize],
[Limit1].[PageSizeOptions] AS [PageSizeOptions],
[Limit1].[PriceRanges] AS [PriceRanges],
[Limit1].[ShowOnHomePage] AS [ShowOnHomePage],
[Limit1].[IncludeInTopMenu] AS [IncludeInTopMenu],
[Limit1].[HasDiscountsApplied] AS [HasDiscountsApplied],
[Limit1].[SubjectToAcl] AS [SubjectToAcl],
[Limit1].[LimitedToStores] AS [LimitedToStores],
[Limit1].[Published] AS [Published],
[Limit1].[Deleted] AS [Deleted],
[Limit1].[DisplayOrder] AS [DisplayOrder],
[Limit1].[CreatedOnUtc] AS [CreatedOnUtc],
[Limit1].[UpdatedOnUtc] AS [UpdatedOnUtc]
FROM (SELECT [Distinct1].[Id] AS [Id]
FROM (SELECT DISTINCT [Extent1].[Id] AS [Id]
FROM [dbo].[Category] AS [Extent1]
LEFT OUTER JOIN [dbo].[AclRecord] AS [Extent2]
ON ([Extent1].[Id] = [Extent2].[EntityId])
AND (N'Category' = [Extent2].[EntityName])
LEFT OUTER JOIN [dbo].[StoreMapping] AS [Extent3]
ON ([Extent1].[Id] = [Extent3].[EntityId])
AND (N'Category' = [Extent3].[EntityName])
WHERE ([Extent1].[Published] = 1)
AND ([Extent1].[Deleted] <> cast(1 as bit))
AND (([Extent1].[SubjectToAcl] <> cast(1 as bit))
OR (([Extent2].[CustomerRoleId] IN (4))
AND ([Extent2].[CustomerRoleId] IS NOT NULL)))
AND (([Extent1].[LimitedToStores] <> cast(1 as bit))
OR (1 /* @p__linq__0 */ = [Extent3].[StoreId]))) AS [Distinct1]) AS [Project2]
OUTER APPLY (SELECT TOP (1) [Filter2].[Id1] AS [Id],
[Filter2].[Name] AS [Name],
[Filter2].[Description] AS [Description],
[Filter2].[CategoryTemplateId] AS [CategoryTemplateId],
[Filter2].[MetaKeywords] AS [MetaKeywords],
[Filter2].[MetaDescription] AS [MetaDescription],
[Filter2].[MetaTitle] AS [MetaTitle],
[Filter2].[ParentCategoryId] AS [ParentCategoryId],
[Filter2].[PictureId] AS [PictureId],
[Filter2].[PageSize] AS [PageSize],
[Filter2].[AllowCustomersToSelectPageSize] AS [AllowCustomersToSelectPageSize],
[Filter2].[PageSizeOptions] AS [PageSizeOptions],
[Filter2].[PriceRanges] AS [PriceRanges],
[Filter2].[ShowOnHomePage] AS [ShowOnHomePage],
[Filter2].[IncludeInTopMenu] AS [IncludeInTopMenu],
[Filter2].[HasDiscountsApplied] AS [HasDiscountsApplied],
[Filter2].[SubjectToAcl] AS [SubjectToAcl],
[Filter2].[LimitedToStores] AS [LimitedToStores],
[Filter2].[Published] AS [Published],
[Filter2].[Deleted] AS [Deleted],
[Filter2].[DisplayOrder] AS [DisplayOrder],
[Filter2].[CreatedOnUtc] AS [CreatedOnUtc],
[Filter2].[UpdatedOnUtc] AS [UpdatedOnUtc]
FROM (SELECT [Extent4].[Id] AS [Id1],
[Extent4].[Name] AS [Name],
[Extent4].[Description] AS [Description],
[Extent4].[CategoryTemplateId] AS [CategoryTemplateId],
[Extent4].[MetaKeywords] AS [MetaKeywords],
[Extent4].[MetaDescription] AS [MetaDescription],
[Extent4].[MetaTitle] AS [MetaTitle],
[Extent4].[ParentCategoryId] AS [ParentCategoryId],
[Extent4].[PictureId] AS [PictureId],
[Extent4].[PageSize] AS [PageSize],
[Extent4].[AllowCustomersToSelectPageSize] AS [AllowCustomersToSelectPageSize],
[Extent4].[PageSizeOptions] AS [PageSizeOptions],
[Extent4].[PriceRanges] AS [PriceRanges],
[Extent4].[ShowOnHomePage] AS [ShowOnHomePage],
[Extent4].[IncludeInTopMenu] AS [IncludeInTopMenu],
[Extent4].[HasDiscountsApplied] AS [HasDiscountsApplied],
[Extent4].[SubjectToAcl] AS [SubjectToAcl],
[Extent4].[LimitedToStores] AS [LimitedToStores],
[Extent4].[Published] AS [Published],
[Extent4].[Deleted] AS [Deleted],
[Extent4].[DisplayOrder] AS [DisplayOrder],
[Extent4].[CreatedOnUtc] AS [CreatedOnUtc],
[Extent4].[UpdatedOnUtc] AS [UpdatedOnUtc]
FROM [dbo].[Category] AS [Extent4]
LEFT OUTER JOIN [dbo].[AclRecord] AS [Extent5]
ON ([Extent4].[Id] = [Extent5].[EntityId])
AND (N'Category' = [Extent5].[EntityName])
WHERE ([Extent4].[Published] = 1)
AND ([Extent4].[Deleted] <> cast(1 as bit))
AND (([Extent4].[SubjectToAcl] <> cast(1 as bit))
OR (([Extent5].[CustomerRoleId] IN (4))
AND ([Extent5].[CustomerRoleId] IS NOT NULL)))) AS [Filter2]
LEFT OUTER JOIN [dbo].[StoreMapping] AS [Extent6]
ON ([Filter2].[Id1] = [Extent6].[EntityId])
AND (N'Category' = [Extent6].[EntityName])
WHERE (([Filter2].[LimitedToStores] <> cast(1 as bit))
OR (1 /* @p__linq__0 */ = [Extent6].[StoreId]))
AND ([Project2].[Id] = [Filter2].[Id1])) AS [Limit1]) AS [Project4]
ORDER BY [Project4].[ParentCategoryId] ASC,
[Project4].[DisplayOrder] ASC
For reference, here is the query plan for this:
Note that all of this is generated for the products is not done via EntityFramework. That is done via the ProductLoadAllPaged stored procedure. That is 620 lines of code, includes dynamic SQL generation and several temp tables.
At that point, I actually looked at the code, and it isn't something that I can actually make easy modifications to, at least not without spending way too long trying to understand what is going on for it to be worth it for a single presentation. So I'm going to leave this aside and look at another app. Probably a sample site, nopCommerce has 44 projects and Orchard has 77 projects. That is too big to actually be able to talk about concisely in a talk.
RavenFS and NServiceBus' Data Bus
The NServiceBus data bus allows you to send very large messages by putting them on a shared resource and sending the reference to it. An obvious use case for this is using RavenFS. I took a few moments and wrote an implementation for that*.
public class RavenFSDataBus : IDataBus, IDisposable
private readonly FilesStore _filesStore;
private Timer _timer;
private object _locker = new object();
private void RunExpiration(object state)
bool lockTaken = false;
Monitor.TryEnter(_locker, ref lockTaken);
if (lockTaken == false)
using (var session = _filesStore.OpenAsyncSession())
var files = session.Query()
.WhereLessThan("Time-To-Be-Received", DateTime.UtcNow.ToString("O"))
foreach (var fileHeader in files.Result)
if (lockTaken)
public RavenFSDataBus(string connectionString)
_filesStore = new FilesStore
ConnectionStringName = connectionString
public RavenFSDataBus(FilesStore filesStore)
_filesStore = filesStore;
public Stream Get(string key)
return _filesStore.AsyncFilesCommands.DownloadAsync(key).Result;
public string Put(Stream stream, TimeSpan timeToBeReceived)
var key = "/data-bus/" + Guid.NewGuid();
_filesStore.AsyncFilesCommands.UploadAsync(key, stream, new RavenJObject
{"Time-To-Be-Received", DateTime.UtcNow.Add(timeToBeReceived).ToString("O")}
return key;
public void Start()
_filesStore.Initialize(ensureFileSystemExists: true);
_timer = new Timer(RunExpiration);
_timer.Change(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
public void Dispose()
if (_timer != null)
if (_filesStore != null)
* This is written to check it out, hasn't been tested very well yet.
Complex nested structures in RavenDB
This started out as a question in the mailing list. Consider the following (highly simplified) model:
public class Building { public string Name { get; set; } public List<Floor> Floors { get; set; } } public class Floor { public int Number { get; set; } public List<Apartment> Apartments { get; set; } } public class Apartment { public string ApartmentNumber { get; set; } public int SquareFeet { get; set; } }
And here you can see an actual document:
{ "Name": "Corex's Building - Herzliya", "Floors": [ { "Number": 1, "Apartments": [ { "ApartmentNumber": 102, "SquareFeet": 260 }, { "ApartmentNumber": 104, "SquareFeet": 260 }, { "ApartmentNumber": 107, "SquareFeet": 460 } ] }, { "Number": 2, "Apartments": [ { "ApartmentNumber": 201, "SquareFeet": 260 }, { "ApartmentNumber": 203, "SquareFeet": 660 } ] } ] }
Usually the user is working with the Building document. But every now an then, they need to show just a specific apartment.
Normally, I would tell them that they can just load the relevant document and extract the inner information on the client, that is very cheap to do. And that is still the recommendation. But I thought that I would use this opportunity to show off some features that don't get their due exposure.
We then define the following index:
Note that we can use the Query() method to fetch the query specific parameter from the user. Then we just search the data for the relevant item.
From the client code, this will look like:
var q = session.Query<Building>() .Where(b =>/* some query for building */) .TransformWith<SingleApartment, Apartment>() .AddTransformerParameter("apartmentNumber", 201) .ToList(); var apartment = session.Load<SingleApartment, Apartment>("building/123", configuration => configuration.AddTransformerParameter("apartmentNumber", 102));
And that is all there is to it.
Mono frustrations
I'm porting Voron to Mono (currently testing on Ubuntu). I'm using Mono 3.2.8, FWIW, and working in MonoDevelop.
So far, I have run into the following tangles that are annoying. Attempting to write to memory that is write protected results in null reference exception, instead of access violation exception. I suspect that this is done because NRE is generated on any SIGSEGV, but that led me to a very different path of discovery.
Also, consider the following code:
using System.IO;
using System.IO.Compression;
namespace HelloWorld
class MainClass
public static void Main (string[] args)
new ZipArchive (new MemoryStream ());
This results in the following error:
Unhandled Exception:
System.NotImplementedException: The requested feature is not implemented.
at HelloWorld.MainClass.Main (System.String[] args) [0x00006] in /home/ayende/HelloWorld/HelloWorld/Program.cs:11
[ERROR] FATAL UNHANDLED EXCEPTION: System.NotImplementedException: The requested feature is not implemented.
at HelloWorld.MainClass.Main (System.String[] args) [0x00006] in /home/ayende/HelloWorld/HelloWorld/Program.cs:11
This is annoying in that it isn't implemented, but worse from my point of view is that I don't see any ZipArchive in the stack trace. That made me think that it was my code that was throwing this.
RavenDB 3.0–Release Candidate & Go Live
Update: We delayed the RC release by a week or two because we wanted to finish the new website. But I decided that it doesn't make sense to at least give you the RC bits so you can play with them. You can look at the new website at http://beta.ravendb.net, it should be done in about a week (we are in a holidays period right now, which slow things down).
I'm taking a break from explaining what is new in RavenDB 3.0 because we have more important news. This is still release candidate, because we want to get more feedback from the field before we can say that this is a final version. The plan is to give the RC a few weeks to mature, and then make a full release. This also comes with Go Live version, so this is fully support for production (and much easier to deal with on production).
This release also include a new website for RavenDB, as well as the updated licensing. Note that we provide a 20% discount for purchases during the RC period. For customers that purchased a RavenDB license since 1 Jul 2014, can upgrade (for no cost) to a RavenDB 3.0 release.
You can go to our site to see how things changes.
Working on Voron…
RavenDB Day: Polyglot Persistence & future directions for RavenDB
In this talk I started out talking about polyglot persistence, but it actually turned out to be more of a discussion of where we want to take RavenDB in the next version (probably 4.0).
RavenDB - Polyglot Persistence from Øredev Conference on Vimeo.


text:
The PASSHE Alumni & Friends Travel Program presents...
Bali to Bangkok & Beyond
21-Day Cruise-Tour with Voyages to Antiquity
*Prices are per person based on double occupancy and include: 3-night pre-cruise package in Bali, 3 nights post cruise in Bangkok with a 2-day air excursion to Angkor Wat (internal flights included), 12-night cruise including an overnight stop in Ho Chi Minh City, Vietnam, all transfers, excursions in each port, tours in Bali and Bangkok, onboard gratuities, $100 per stateroom onboard credit, all meals onboard the ship with a choice of restaurant and open-seating dining so you can choose when, where and with whom to dine; complimentary wine, beer and soft drinks with your evening meal PLUS a $100/stateroom shipboard credit.
AIR: Philadelphia and Pittsburgh $1,095 per person; Newark $995 per person.
Other air cities available. Please call for rates.
Standard Inside Cabins (Category N) $4,995.00
130 sq ft staterooms located on Belvedere and Columbus Decks. Fixed twin beds with private shower
Premium Inside Cabins (Categories M & L) $5,350.00 - $5,695.00
130 sq ft staterooms located on Columbus and Belvedere Decks. Fixed twin beds with private shower
Standard Outside Cabins (Category K) $5995.00
Premium Outside Cabins (Categories J - H) $6350.00 - $6795.00
Deluxe Outside Cabins (Categories G & F) $7,250.00 - $7,550.00
Deluxe Balcony Cabins (Categories D & C) $8,550.00 - $8,895.00
Junior Suite with Balcony (Category B) $9,650.00
Owner's Suite with Balcony (Category A) $10,395.00
Not included: Visa fees and government taxes of $93.00 per person.
Deposit: A 10% deposit is due within 7 days of making your reservations.
Final Payment Date: October 15, 2012.
Special offers may exist at time of booking. You will always receive the lowest available price.
SPACE IS LIMITED SO BOOK SOON FOR BEST AVAILABILITY! Reservations after that date will be accepted as long as space is still available. Remember, Aegean Odyssey carries only 350 passengers so space is limited!Book early to avoid disappointment!
For reservations and information call Christie (ext. 107) or Craig (ext. 103) at Cruisin' - (610) 341-1979 or (800) 506-7447
Book now to guarantee your spot on this great trip!
Cruisin' is not responsible for any rate and/or availability changes and we reserve the right to correct any errors
Disclaimer of Liability: In the absence of its own negligence, Cruisin' Inc., and the State System of Higher Education and its 14 institutions, its agents, offices and/or suppliers of services shall not be responsible for any cancellations, delays, diversions or substitution of equipment or any act or omission whatsoever by sea or air or land carriers, hotels, cruise lines, transportation companies, restaurants, tour operators, excursion operators, automobile rental agencies, or any other persons providing any services or accommodations to passengers, including without limitations, any results thereof, such as changes in services or accommodations. Crusin' Inc., its agents, offices and/or suppliers of services pursuant to or in connection with any itineraries act only as agents for the passenger solely and exclusively for the purpose of making arrangements for hotels, transportation, tours, excursions, restaurants, automobile rentals, or any other service, and does not assume any liability whatsoever for any personal injury, property damage, death, loss accident of delay to person or property due to an act or omission of any sea, air or land carrier, hotel, cruise line, restaurant, automobile rental agency, company or person rendering any of the services included in the tour, or by act of God. Further, no responsibilities are accepted to damage or delay due to sickness, pilferage, labor disputes, machinery breakdown, quarantine, government restraints, political unrest, war, riots, rebellion, insurrection, weather or other causes beyond their personal control. No responsibility is accepted for any additional expense, omissions, delays, re-routing, or acts of government or authority. This agreement shall be construed in accordance with and governed by the State of Pennsylvania. In the event any matter of disagreement shall arise in connection with the agreement, the sole and exclusive venue for such litigation instituted by either party shall be laid in the Court of Common Pleas, Country of Delaware, State of Pennsylvania.

subset: commoncrawl


text:
Introduction by Don George!
Photographer Barry Brukoff presents Royal Cities of the Ancient Maya ($50.00). Leading Maya scholar, Michael D. Coe, and Brukoff, one of the world's finest photographers of ancient sites, bring the rich cultural heritage of the Maya vividly and authoritatively to life in this new work—irresistible to everyone from the casual visitor to Pre-Columbian experts.
Please note: this event is SOLD OUT!
We'll all be clamoring to go to the Left Bank to celebrate Hubert Keller's Souvenirs: Stories and Recipes from My Life, the new book by one of America's most talented chefs, Hubert Keller. Raised in Alsace France, Keller was destined to be in the kitchen as he grew up above his father's patisserie. He apprenticed under many great French chefs until he landed in San Francisco and became the chef/owner of the popular Fleur de Lys restaurant along with his wife Chantal and Maurice Rouas. Chef Keller has been named the James Beard Foundation's "Best Chef: California."
Don't wait to sign up - space is limited. Price includes the meal, wine, tax, tip & a signed copy of the author's book. Reserve at Book Passage (415-927-0960) or at bookpassage.com/food-wine-events Can't attend the event? Order a signed copy.
In conversation with Jason Roberts
Peter Orner talks about his novel Love and Shame and Love ($14.99). Covering four generations of one family, Orner illuminates the countless ways that love both makes us whole and completely unravels us. A comic and sorrowful tapestry of memory, of connection and disconnection, this work explores the universals with originality and wisdom.
Jason Roberts is author of the bestselling A Sense of the World: How a Blind Man Became History's Greatest Traveler, a biography of James Holman, the blind adventurer of the early 19th century.
Also appearing: Sebastien Rouxel
Featuring Bouchon Bakery baked goods and coffee/tea service
Chef Thomas Keller shares his newest cookbook, Bouchon Bakery ($50.00). This cookbook, Keller's fifth, is a joyous exploration of his favorite all-American childhood treats and of the classic French pastries he adored as a young chef in Paris. Written with Sebastien Rouxel, who oversees pastry for The French Laundry, the Bouchon Bakeries, and per se, Bouchon Bakery is a wonder of beauty, playfulness, and inspired technique. Its recipes are marvels of ingenuity and simplicity.
Thomas Keller, author of The French Laundry Cookbook, Bouchon, Under Pressure, Ad Hoc at Home, and Bouchon Bakery, has six restaurants and six bakeries in the U.S. which continue to elevate the industry's standards. Keller's three-star Michelin Guide-rated fine dining restaurants, The French Laundry and per se, are considered two of the best restaurants in America and are consistently ranked among the top five eateries in the world.
Priority seating to this Book Passage event with purchase of the author's new book from Book Passage.
Charlotte Cheng has worked as a freelance illustrator and educational consultant for a variety of projects and companies including Walt Disney Imagineering and LeapFrog. Her debut as a picture book illustrator in A Moment in Time ($17.99) features a heartwarming tale of a family's photo-taking fun on a fine summer day. It's a perfect gift for any aspiring photographer or scrapbooker and a wonderful lesson about the value of capturing family moments. Come join Charlotte as she shares her journey in turning moments into memories and memories into universally accessible stories. Whether you're a writer, an illustrator, or just a lover of picture books, there is a story inside you that is waiting to be shared!
Margo True discusses The Sunset Essential Western Cookbook: Fresh, Flavorful Recipes for Everyday Cooking ($24.95). Awesome enchiladas; cool, crunchy Caesar salad—these iconic Western recipes are matched with 150 full color photos. The recipes include the best loved versions of the dishes tested by Sunset's food editors.
Told with self-lacerating honesty and unvarnished prose that rises on command to poetic intensity, Lucille Lang Day's Married at Fourteen ($16.95) is the absorbing memoir of a young woman who struggles to find storybook romance and a purpose in life beyond it—and, against cruel odds, succeeds.
Lucille Lang Day's first poetry collection, Self-Portrait with Hand Microscope, received the Joseph Henry Jackson Award. She received her M.A. in English and M.F.A. in creative writing at San Francisco State University. She is also the founder and director of the small press Scarlet Tanager Books.
Join Book Passage and Scottevest founder Scott Jordan for an exclusive holiday sale and celebration! Scottevest jackets and vests feature specially designed pockets for a streamlined look that allows you to carry essential accessories safely, stealthily, and comfortably.
· All Scottevest items 20% off during the show
· A first look at brand new Scottevest merchandise
· "What's in your Scottevest" contest
· How to get the most out of your Scottevest workshops with Scott himself!
· Door prizes
· Refreshments
Scottevests - the most stylish way to travel
Mastering Children's Writing
A New Workshop Salon Led by Andrea Alban
2nd Sunday each month • Corte Madera
5:00-8:00 pm • $180 per year (annual membership comes with one free private consultation with Andrea, a $60 value!) or $30 per monthly meeting
Spark your imagination and polish your manuscript in a community of enthusiastic writers. Listen to an engaging craft presentation, practice new writing and editing techniques, give and receive peer feedback, and go home to your desk with a monthly assignment — energized and inspired. Craft topics will include style and voice, point of view, characterization, fictional time and place, plot and story arc, and the art of revision. We will also explore manuscript submission, book promotion, and establishing an online presence and platform as a writer. Andrea Alban is the author of nine books including The Happiness Tree and a YA novel, Anya's War. She holds a B.A. in Creative Writing.
Register for annual membership:
Register >>
Register for one session:
Register >>
Phil Cousineau shares The Painted Word ($16.95). Whether old-fangled or brand new, all the words included in this new work possess an ineffable quality that makes them luminous. To untangle the knot of interlocking meanings of these painted words, logophile and mythologist Phil Cousineau begins each fascinating word entry with his own brief definition. He then fills it in with a tint of etymology and a smattering of quotes that show how the word is used, ending with a list of companion words.
Phil Cousineau is an award-winning writer and filmmaker, teacher and editor, independent scholar and travel leader, storyteller and TV host. His fascination with art, literature, and the history of culture has taken him from Michigan to Marrakesh, Iceland to the Amazon, in a worldwide search for what the ancients called the "soul of the world."
Join the Left Coast Writers literary salon for a special holiday celebration. The Left Coast Writers will share food, drink and a celebration of the holidays in stories and poems. They'll also share their recommendations for the best book gifts this season.
This event will feature a display of costumes worn by Michael Jackson throughout his career!
Designer Michael Bush shares The King of Style: Dressing Michael Jackson ($45.00). This work is a fascinating look at the intersection of music and fashion, as well as an homage to Michael Jackson's brilliant fusing of costume, personality, and performance to create his iconic image. This is the first art-driven book about the costumes, apparel, shoes, and accessories worn by Michael Jackson, including hundreds of lavish photographs and a behind-the-scenes look into the process of collaborating with him on the making of his wardrobe, written by his longtime costume designer Michael Bush.
Penn Jillette presents Every Day is An Atheist Holiday ($25.95). The larger, louder half of legendary magic act Penn & Teller, and New York Times-bestselling author of God, No!, is back with a new collection of spiritual rants and hilarious ravings - the perfect year-round gift, when you consider that every day is an atheist holiday.
Penn Jillette has published numerous articles in The New York Times, The Wall Street Journal, Los Angeles Times, Playboy, and elsewhere. He is the author of the novel Sock and the comedic How to Cheat Your Friends at Poker (coauthored by Teller). He lives in Las Vegas, Nevada.
Rebecah Freeling is a master storyteller, experienced early childhood educator, and parent coach. New to California, she recently joined the faculty of Marin Mountain School Early Childhood Center in Corte Madera. For thirteen years she was owner, Director and Lead Teacher of Briar Rose Children's Center in her home state of Ohio. Her magical stories, both original and drawn from the folk and fairy tale traditions, are enhanced by handmade table puppets and simple marionettes. One often observes the children hearing her stories to be sitting on the edge of their seats, eyes wide and mouths open in anticipation!
Special for kids!
Jan Klyce presents Andrew's Wish ($15.95). Andrew finds a box of gifts that Santa left behind. He carries the box over the snow covered hills to find the kingdom of the elves, hoping the gifts can arrive by Christmas morning. In this timeless story, Andrew transports himself into the heart of every reader with his message of love. Includes a CD narrated by Kelsey Grammer.
Rebecah Freeling is a master storyteller, experienced early childhood educator, and parent coach. New to California, she recently joined the faculty of Marin Mountain School Early Childhood Center in Corte Madera. For thirteen years she was owner, Director and Lead Teacher of Briar Rose Children's Center in her home state of Ohio. Her magical stories, both original and drawn from the folk and fairy tale traditions, are enhanced by handmade table puppets and simple marionettes. One often observes the children hearing her stories to be sitting on the edge of their seats, eyes wide and mouths open in anticipation!
Lisa Alcalay Klug shares Hot Mamalah ($18.99). This "ultimate guide for every woman of the tribe" is a start-to-finish celebration of the strengths, challenges, and triumphs of Jewish women—the good, the great, the PMS-y, and the menopausal! This "ABCs of She" dishes up a delicious smorgasbord of everything whole-y and holy feminine for having fun and having chutzpah, with humorous essays, adorable illustrations, how-to's and more. From cocktails to cupcakes, Purim costumes to bar aliases, Hot Mamalah whets an appetite for getting the most out of life, love, and your closet. Hot Mamalah is the much anticipated companion to the hilarious 21st century Jewish catalog, Cool Jew.
Left Coast Writers® Literary Salon at Book Passage in Corte Madera
Author Constance Hale presents Vex, Hex, Smash, Smooch: Let Verbs Power Your Writing ($26.95). Synthesizing the pedagogical and the popular, the scholarly and the scandalous, Hale combines the wit of Bill Bryson with the practical wisdom of William Zinsser. She marches through linguistic history to paint a layered picture of our language—from before it really existed to the quirky usages we see online today.
Constance Hale is the author of Wired Style and Sin and Syntax. She has taught at the Nieman Foundation for Journalism at Harvard University and UC Berkeley Extension. She is based in San Francisco, California.
Book Passage hosts the monthly meetings of Left Coast Writers® at our Corte Madera store. This Literary Salon is led by author/teacherLinda Watanabe McFerrin. The monthly meetings provide an evening of literary connections, support, counsel, provocative readings, writing tips, literary chat, unabashed networking, and great fun. Each meeting also features a presentation by one of several Bay Area literary figures. The fee includes membership in Left Coast Writers®, a group of new and experienced writers. LCW has its own lively newsletter and website at www.leftcoastwriters.com/.
George Howe Colt shares Brothers: On His Brothers and Brothers in History ($30.00). Colt's new book is an idiosyncratic and masterful blend of memoir and history featuring both the author's three brothers and iconic brothers in history—the Booths, the Van Goghs, the Kelloggs, the Marx Brothers, and the Thoreaus. Illuminating and affecting, this book will be revelatory for any parent of sons, any sibling, anyone curious about how a man's life can be molded by his brothers.
George Howe Colt is the bestselling author of November of the Soul: The Enigma of Suicide and The Big House, which was a National Book Award finalist and a New York Times notable book. He lives with his family in Western Massachusetts.
Book proceeds for this evening will benefit a TBA children's charity
CEO of AVG Technologies N.V., JR Smith, and its Chief Policy officer Siobhan MacDermott have come together to author Wide Open Privacy: Strategies for the Digital Life, a guide to help users take control of their privacy in an ever more digital age.
Far from being a "Privacy for Dummies" approach, the book aims at covering everything from governmental policy to individual privacy concern, and considers both the private and commercial expectations on personal data. After all these are going to be some of the hottest political topics we face in the next few years; how do you begin to legislate something as vast, international and free as the internet which spans multiple cultures, languages and governments?
Siobhan MacDermott is one of the foremost global authorities on the future of Information Technology, consumer dynamics, cybersecurity, privacy, and business leadership.
In his first-ever collaboration, New York Times bestselling author James Rollins combines his skill for cutting-edge science and historical mystery with award-winning novelist Rebecca Cantrell's talent for haunting suspense and sensual atmosphere in a gothic tale about an ancient order and the hunt for a miraculous book known only as . . . The Blood Gospel ($27.99).
James Rollins is the New York Times bestseller of thrillers translated into forty languages. His Sigma series has been lauded as one of the "top crowd pleasers" (New York Times) and one of the "hottest summer reads" (People Magazine).
Rebecca Cantrell's Hannah Vogel mystery novels have won the Bruce Alexander and Macavity awards and been nominated for the Barry and Romantic Times Reviewers Choice awards; her critically-acclaimed novel, iDrakula, was nominated for the APPY award and listed on Booklist's Top 10 Horror Fiction for Youth.
Join Linda Watanabe McFerrin and the Left Coast Writers® for an evening of love stories to help set the mood for Valentine's Day. You can count on the talented writers from LCW to provide an entertaining evening full of love, lust and other appropriate emotions.
There'll be wine an chocolate, of course, AND all who attend are invited to bring a love or lust story of 1000 words or less. Their stories will be considered for publication on the hotflashessexystsories.com website and a $100 award. You must be present to enter.
Sign up here:
Paul H. Landes reads from Wings to Redemption. A compelling story that is part high-tech thriller, part government espionage and frighteningly realistic, Wings to Redemption features scientific research and unexpected love all set against the beautiful backdrop of Marin County.
Paul H. Landes began his career in corporate real estate when he lived in Marin County, with his profession eventually taking him throughout the western United States. He became a full time author in August of 2011.
Join three authors for a "triple feature" evening of music, refreshments and live readings! Carol Newman shares Radical Feminist in a Topless Band ($12.50), a memoir chronicling her time as a musician in the early seventies. Cynthia Greenberg presents Burmese Jade: A Novel ($17.50), where thirteen strangers lives become entangled with the fate of the Kalichakra gems. Nicola Trwst reads from Belvedere Club ($12.95), a murder mystery set in our very own Marin County.
Join A Band of Wives founder Christine Bronstein and select contributors as they read from Nothing But The Truth So Help Me God: 51 Women Reveal The Power of Positive Female Connection ($14.95 ). This first book from the women's social network group A Band of Wives brings together essays, poetry, and artwork focused on themes within the self-help and personal improvement genre. The authors and artists are women from around the globe, varied racial and ethnic groups, socioeconomic backgrounds, and ages: everything from famous authors, celebrities, and entrepreneurs, to nannies, soccer moms, and starving artists.
Christine Bronstein is the founder of ABandOfWives.com, a social network and information website for women. She was CEO of one of the few female run venture-backed health and fitness companies in the nation for 8 years and president of a child-welfare foundation for 3 years. She is a graduate of the Columbia/UC-Berkeley executive MBA program and a member of the honor society Beta Gamma Sigma.
Cost: $12/person
Help us celebrate the New Year by sipping our fabulous new wine selection. Enjoy 6 tastes, a glass of your choosing, delicious treats and great company! To be held in the Book Passage Cafe.
Hope to see you there. Cheers!!
Whitney Houston's voice. A voice of raw power and angelic sweetness, tremendous range, and incredible control. When the world first heard it back in 1984, a new chapter was written in the annals of popular music. Author Narada Michael Walden sat in the cockpit alongside Whitney while her career skyrocketed, producing many of the hits that today comprise her musical legacy—among them, "How Will I Know," "I Wanna Dance with Somebody," "Where Do Broken Hearts Go," and "One Moment in Time." In Whitney Houston: The Voice, the Music, the Inspiration ($24.95), his intimate stories of their unforgettable times together, both inside and outside the recording studio, draw a portrait of a smart, funny, compassionate woman whose striking physical beauty was matched by her inner strength and justifiable self-confidence.
Rebecah Freeling is a master storyteller, experienced early childhood educator, and parent coach. New to California, she recently joined the faculty of Marin Mountain School Early Childhood Center in Corte Madera. For thirteen years she was owner, Director and Lead Teacher of Briar Rose Children's Center in her home state of Ohio. Her magical stories, both original and drawn from the folk and fairy tale traditions, are enhanced by handmade table puppets and simple marionettes. One often observes the children hearing her stories to be sitting on the edge of their seats, eyes wide and mouths open in anticipation!
Join Aaron Ableman and friends as they present a musical storytelling experience in conjunction with his children's book Pacha's Pajamas. Being touted by critics as "the next Dora", this thought-provoking children's story follows a city girl on her adventures to change the world. Pacha is the only human invited to a gathering of the plants and animals of Mother Earth and she must figure out how to bring balance to the planet. They build a stadium powered by electric eels to host fun-filled acts including an insect band called The Beetles, a black-eyed pea rapping for a better world and a beaver named "Justin-Time." At the end of the show, Pacha shares an important message for all of nature and humanity.
For the past 13 years, Aaron Ableman has been presenting platforms for ecological education through storytelling, art and music. An author, acclaimed educator, and urban farmer, Ableman uses a unique combination of arts disciplines for ecological & wellness education. Ableman has launched youth arts initiatives, green job trainings and ecological remediation projects across the US, in northern India, throughout Havana, Cuba, and in the indigenous reservations of northern Canada.
A sometime-stand-up comedian by night, an all-the-time writer and teacher by day, Mark Maynard has taught community college students about narrative arc, helicopter skied after stories for a local newspaper, thrown in his lot with a start-up dotcom biz, and coordinated play-dates for his two boys as a stay-at-home dad. It's no wonder Maynard chose to write about a city as transformative as Reno, Nevada. Each of the eight stories in his debut novel, Grind ($15.95), introduces characters striving and struggling in "the Biggest Little City."
Coming early for a reception with Ferry Plaza Farmers Market refreshments!
Douglas Smith presents Former People: The Final Days of the Russian Aristocracy ($30.00). Historically compelling and told with "brutal clarity," Douglas Smith's unprecedented account of the Russian aristocracy is the first book in any language to examine the fate of the nobility during and after the Bolshevik Revolution.
Douglas Smith is an award-winning historian and translator and the author of three previous books on Russia. Before becoming a historian, he worked for the U.S. State Department in the Soviet Union and as a Russian affairs analyst for Radio Free Europe/Radio Liberty in Munich. He lives in Seattle with his wife and two children.
By the time you're finished reading Financially Fearless: The LearnVest Program for Taking Control of Your Money ($19.99), you'll walk away with a financial game plan tailored to your priorities, your hopes and dreams, and your lifestyle. And, because von Tobel and the team at LearnVest are experts at financial planning in the online era, you'll also learn how to integrate your financial plan into your mobile, social, digital life. Like your own personal financial planner between two covers, this book will set you up for a secure, worry-free money future, without having to give up things you love.
Please call (415) 927-0960 to inquire about remaining space.
Joanne Weir, a James Beard award-winning chef, demystifies cooking techniques and gives the home chef 100 recipes for main courses that are easy, comprehensive and delicious. Written as the companion cookbook to her new TV show, Joanne Weir's Cooking Confidence, it will put the mojo back into your kitchen. Weir is the author of From Tapas to Meze, You Say
Erica Bauermeister shares The Lost Art of Mixing ($25.95). In prose to be savored, Bauermeister brings back some of the most engaging characters from School and introduces intriguing new personalities as she follows them around the seasons of a year. At the heart of her story once again is Lillian, the chef and restaurant owner with a remarkable ability to bring out the hidden essence of people as well as ingredients, and to combine both in surprising, delightful new ways
Erica Bauermeister, the bestselling author of The School of Essential Ingredients and Joy for Beginners, is also the coauthor of 500 Great Books by Women: A Reader's Guide and Let's Hear It for the Girls: 375 Great Books for Readers 2-14. She has taught literature and creative writing at the University of Washington, from which she holds a Ph.D. in literature, and is a graduate of Occidental College.
Julia Flynn Siler talks about Lost Kingdom: Hawaii's Last Queen, the Sugar Kings, and America's First Imperial Adventure ($16.00). Deftly weaving together a memorable cast of characters, this work brings to life the ensuing clash between a vulnerable Polynesian people and relentlessly expanding capitalist powers. At the center of the story is Lili'uokalani, the last queen of Hawaii. Born in 1838, she lived through the nearly complete economic transformation of the islands.
Julia Flynn Siler is an award-winning journalist. Her book, The House of Mondavi: The Rise and Fall of an American Wine Dynasty, was a New York Times best seller. She has written for Business Week and the New York Times, and is now a contributing writer for the Wall Street Journal in San Francisco.
Marin author Jean Davison, former teacher at Redwood and Drake and, more recently, an anthropologist and founder of IDEA, an international development partnership organization launched in Marin in the 1980s, returns to Book Passage with her newest book, Mother of Fire: An Iraqi Woman's Journey from Mosul to Malawi.
Colin Winnette is a writer and performer living in Chicago. He was a finalist for the 1913 First Book award, and has published one novel, Revelation, and one collection of short prose, Animal Collection. Read more about Colin and his work at colinwinnette.tumblr.com.
Admission: $40 at the door
Price of admission includes a signed copy of All Natural
Rebecah Freeling is a master storyteller, experienced early childhood educator, and parent coach. New to California, she recently joined the faculty of Marin Mountain School Early Childhood Center in Corte Madera. For thirteen years she was owner, Director and Lead Teacher of Briar Rose Children's Center in her home state of Ohio. Her magical stories, both original and drawn from the folk and fairy tale traditions, are enhanced by handmade table puppets and simple marionettes. One often observes the children hearing her stories to be sitting on the edge of their seats, eyes wide and mouths open in anticipation!
In Expanding the Pie ($29.94), Susan Ross provides useful tools and frameworks for designing, implementing and evaluating effective relationships, the basis of all partnerships. Whether you are an individual, consultant or organization these tools and strategies can be beneficial. Sharing collaborative case studies, Ross will identify factors that make partnerships successful and offer lessons that managers and individuals can use for future opportunities.
Susan Rae Ross is the founder and CEO of SR International, a consulting company that provides corporations, nonprofits and government agencies with strategies and tools to actively facilitate successful partnerships across traditional sectors.
Join Jane Hirschfield, Persis Karim, José Luis Gutiérrez, Dana Teen Lomax and editor Beau Beausoleil as they read from Al-Mutanabbi Street Starts Here: Poets & Writers Respond to the March 5, 2007 Bombing of Baghdad's "Street of Booksellers" ($20.00).
On March 5th, 2007, a car bomb was exploded on al-Mutanabbi Street in Baghdad—the historic center of Baghdad bookselling—wounding more than 100 people and killing more than 30. This anthology begins with a historical introduction to al-Mutanabbi Street and includes the writing of Iraqis as well as a wide swath of international poets and writers who were outraged by this attack. Exploring the question "Where does al-MutanabbiStreet start?", the book looks at both communities and nations, seeking to show the commonality between a small street in Baghdad and other individual cultural centers and explain why this attack was an attack on us all. Chapters examine al-Mutanabbi Street as a place for the free exchange of ideas, a place that has long offered its sanctuary to the complete spectrum of Iraqi voices, and a place where the roots of democracy took hold many hundreds of years ago.
Beau Beausoleil is the founder of the Al-Mutanabbi Street Coalition and the author of Concealed in Language. Deema Shehabi is a Pushcart Prize–nominated writer who has contributed to numerous journals, including the Kenyon Review, Literary Imagination, and Poetry Review (London). She is the author of Thirteen Departures from the Moon. They both live in San Francisco.


text:
Group Fitness
♦ Find a Schedule7 - Day Free Trial Offer
♦ Get Started TodayLooking for a Career?
♦ Join Our TeamMember Testimonials
♦ What's Being Said
Healthy Food Choices
Nutrition Tip:
Click here for the entire article!
Fuel your body with nutritionally rich and delicious foods. Packed with healthy eating recipes, this document will teach you the basics of making food choices that will truly benefit your health. Learn how our bodies respond to protein, fats, and carbohydrates, and cook for your health!
Click here for the entire article!


text:
Hic Iacet
Last Known Status: Active
Latest Hic Iacet News
Below is our complete Hic Iacet news coverage, including columns and articles pertaining to the band. Some articles listed may be indirectly related, such as side projects of the band members, etc.
Hic Iacet Streaming 7"
Hic Iacet is streaming two tracks from its new "Prophecy Of Doom" 7" over on Bandcamp. These are incomplete teaser tracks of the 7" it will be releasing on October 31st via Hells Headbangers Records. The disc will be pressed on black vinyl and 100 copies will be on swamp green vinyl with black splatter. The mysterious Spanish entity of Hic Iacet is rumored to include various movers and shakers of the underground, and also equally rumored to be a solo-project of one supremely sick individual. Five members or none, Hic Iacet's released its debut demo "Hedonist of the Death" last year.


text:
Enhance the aesthetics and flexibility of your home theater with the Peerless IM760P In Wall Mount with Pivot Arm for 32-71 inch flat panel screens. With integrated removable outlet receptacles and cable access plates inside the mount, the IM760P conceals your TV mount, cables and cords by recessing them into the wall, allowing your TV to be completely flush against the wall surface for a seamless and organized look.
The included pivot arm comes with an adapter plate for screens with VESA compatibility, and it can extend 18 inches from the wall. Better yet, it can tilt forwards 10 degrees and backwards 5 degrees, swivel left and right 45 degrees, and roll 7 degrees.
Stud-locating tabs that center the in wall mount between 16 inch wood or metal stud centers makes installation easy, so you can enjoy your home theater system with the IM760P sooner.
*Screen will be positioned flat against the wall when used only with VESA®100/200x100/200x200mm compliant flat panel screens. Addition of adapter plate will increase distance from wall.
Overall Rating for In Wall Mount and Pivot Arm for 32-71 inch Flat Panel TVs


text:
Psych Midseason Finale Review: All Grown Up?by Chandel Charles at . Comments
It was like the world got turned upside down on Psych this week.
Just as Shawn looked like he was growing up and taking his relationship with Juliet to the next level, Gus, Lassiter and Henry digressed in age... to the point they engaged in bro-speak. And that was only HALF of what happened on "Neil Simon's Lover's Retreat!"
So much went down in this installment, I barely know where to start. So let's go with the obvious: Jason Priestley!
Many of you know him from the original 90210, but here we got to see him as a loveable conman/thief, Clive, paired with a gorgeous Jennifer Finnigan as his wife, Barbie. A shout-out to Bonnie and Clyde? I'd have to imagine so.
It was so fun to watch Priestley and Finnigan together as a couple. They were lovey-dovey and over-the-top, but I loved it. I don't think the casting department could have made a better match. They look exactly like Shawn and Juliet, plus they are criminals while the latter two are a psychic/cop. It's the little things, people!
As for Tony Hale, way to be the bad guy. We wanted to feel sympathy for you, and you made it so easy, until you shot someone. Then all bets were off. Props to you.
And so at this time I must laud the writing of newcomer Carlos Jacott. I don't know how many episodes you are responsible for thus far, if any, but if this is your first (as I strongly suspect it is) you are off to a flying start. You will no doubt join the incomparable ranks of Franks, Berman, Harthan, Meltreger, Patterson et. al. in no time.
Not only did you manage to write a thoroughly entertaining and quotable episode, you also unraveled several important plot lines in a way that was true to Psych without dropping it on the audience as if to say "Here you go."
With all the technical praises out of the way, we can finally discuss that shocker. Or was can we even refer to it as that?
I don't know about you, but from the moment Shawn started asking Gus to read his mind, I knew something was up. A big something.
That thought was only reinforced when Shawn began having a heart attack about the stuff from the room being stolen. Shawn barely has any possessions in the first place. He's the first person to admit that. And yet now, of all times, he chooses to start flipping out?!? Of course there was an engagement ring somewhere!
What I found particularly intriguing about all of this was how Shawn managed to keep his purchase of the ring off the radar. Clearly Shawn used Gus's credit card to pay for the trip (and with a fake Burton Guster state identification card, no less), which we've seen happen before. But how is it that Shawn was able to acquire enough cash that he could buy a ring such as that?!?!
This says two things: One, that Shawn really is thinking about a future with Juliet, in a very serious way. Two, that Shawn is, in fact, capable of managing finances in an adult manner (a.k.a that he's able to spend his own money on things he that are really important to him).
I continue to find it interesting how Shawn is always attempting to take things to the next level when Juliet isn't even on that level yet. Remember when he asked her in a drugged and drunken stupor to move in? It's like for every moment he is less mature than everyone around him, he magically pops up with these profound moments of maturity.
It's as if he's consciously not ready for the next level, but subconsciously he is. Who knows what will become of Shawn when he finally reconciles those two sides?
We could ask Gus, except he's too busy being a player in the club. And teaching Lassiter and Henry how to be players, too. Or is it Henry really doing the schooling? It's hard to tell.
While Shawn was having a maturity epiphany, Gus's off-the-hook weekend took a surprisingly hilarious turn when he inadvertently invited Lassiter and Henry on his "biddie hunting trip."
If I ever hear the word "hizzy" come out of Lassiter's mouth, or "player" come out of Henry's mouth, again, I don't know what I will do.
Any time these three men get together, it's like they can't help but be bros. I don't know the last time I heard Lassiter refer to Henry as an idiot. You don't do that with a work colleague - at least not when you're as old as they are.
It's a definite indicator of how far these characters have continued to grow in their relationships with one another. I love watching it. I think this has been the best season yet to watch the pairings switch-up and play out.
It's a shame Psych won't be back until early 2012. But in the meantime, we have a ton of material to deal with!
How will Gus react to Shawn's almost-proposal? What impact will it have on Gus's quest for a steady girlfriend of his own? Sound off below!
C. Charles is a TV Fanatic Staff Writer. Follow her on Twitter.Tags: Psych, Reviews
My concern is that these tests he's tanklig about were animals exposed to AIR containing PG. As? humans, we are inhaling it directly into our lungs and it's heated. Isn't that going to have a significant difference in the effects?For the record, I am an e-cig smoker and they are amazing but there really needs to be a more modern day study on this. I'm surprised that hasn't happened by now since they're so popular.
So this was definitely my favorite episode. Hands-down.I've watched it about a million times, and I still squeal at every kiss, all the romance, and....DUH! The ring!!!! I have to say though, I love Psych and all, but Shawn should not propose without Jules knowing the truth. It's just wrong. I think they should wait...but, Hey....The aren't. Didn't James say something about a wedding for the series finale? >_> well, he also mentioned it's not who yo think it would be...or is just twisting out minds? Well, let's hope that Shawn and Jules actually do get married, but before the series. I wonder how Jules' is gonna react to the truth? But for some reason, I feel, I sense (sorry that felt needed-LOL), that Jules already knows.
I am so glad that Shawn is growing up to be the man he wants to be. Yes, he's a little less mature but I think that we all have those moments when we have the times of our lives. The minute I saw that Shawn was trying to get Gus-Gus (Sorry, that's my nickname for Gus) to read his mind, I was like, "Yeah, something is up..." and the first thought that went through my mind was "He's actually going to pop the question to her." And I was right but I wondered why Shawn about died because of the DS being stolen. That was what shocked me. Have you ever noticed that Shawn and Jules are like the awesome couple? That they have the chemistry? Well, due to their personal lives off the screen, James and Maggie are actually together. I had no clue until the other day when I was googling James. LOL! But those two are AWESOME!
No, no, no, no...FAIL! No way Shawn is ready for proposal. No matter how grown up he is becoming, concious or subconcious! He may just be going along with what he "think" Jules wants him to do. She summed things up perfectly, both when first leaving in the car and then walking along at the end. ANNNNND, there is no way Shawn would/should take the relationship to that level without Jules knowing the truth about his abilities. It would just be way too high a fall from that height in their relationship. No way Shawn proposes without asking newly-found Jules' Dad! Especially after all the bonding that was done. No way he doesn't old school it and ask for his blessing first...AND, gets him hysterically involved in a lame-brain production for over-the-top proposal scheme. No Woody? How could they have left out Woody on the guy's ("gentleman's") weekend? He has firmly been added to the group dynamic and would have been a wildly funny addition to the lame club scene. Love how Henry took the bar nap with him right away when they all went off to win the bet. Please don't let Lassie say "hizzle" again. No, Juliette would not have kept from switching automatically into detective mode the minute they found the break in. She is inherently a cop and she would have flipped the switch like a reflex. Great time with Shawn & Jules. They are so comfortable together.
Great moments, great guest stars, but overall disappointing.
Drop a grape...
"No one brought vegetables?"
"So YOU got all the lightbulbs!"
Fabulous ending. It took me totally by surprise but the beauty of it was that, looking back through the story, you could see how perfectly all the pieces fit together. Kudos to the writers! And I loved the camaraderie among the trio of love losers. They were all wonderful. Actually the least interesting character on last night's episode was Shawn. Apparently the more mature he gets, the less outrageous he is. That might not speak well for a future with Juliet. Or a wrap up of the whole show.
Great episode! In general, the first half of Season 6 was very very strong. But has there been any word on a pickup for Season 7? It seems like they're usually renewed by this point, and ratings have certainly been down. Even so, with the character development still ongoing and the storylines so strong, it'd be heartbreaking to have them stop after the Feb/Mar batch of new shows!
Wow Shawn was going to propose to Juliet. I loved the kisses. It was a very funny episode.
Absolutely PERFECT. I just couldn't begin to pick out my favorite scene, except to say the three amigos out picking up chicks makes me laugh out loud just thinking about it (although the only way to make it better would be to add Woodie). Kudos to all for a great mini season, it was worth waiting through the summer just to see these wonderful episodes. Now the coming attraction tease us with a return visit by the Shat, pls pls pls a little Star Trek, at least a little tribble somewhere. Hooray, look forward to next year.
it was just perfect!! i love shawn + juliet!
I always enjoy reading your reviews C. Charles :D