We’ve seen a bunch of folks asking recently if their Exchange 2007 CAS server can talk to their Exchange 2003 mailbox server. The answer is <gasp> it depends on what you mean.
It depends on what technology you are referring to and what you mean by “talk.” Are you referring to WebDAV calls? Then yes. Are you referring to OWA? Then sorta. Are you referring to Exchange Web Services (EWS), then no. There are really two things at play here: proxy and redirection. That is, can an Exchange 2007 CAS server serve as a proxy for calls to the backend mailbox server, or can it successfully redirect calls to the mailbox server where the call can be handled.
In Exchange 2003, HTTP calls were simply forwarded on from the front-end to the back-end. The back-end server would receive the HTTP request and handle it and then forward the response back up through the front-end. In Exchange 2007, however, the front-end CAS handles the HTTP request and speaks RPC to the back-end server.
When a request is received by a CAS server, it knows how to figure out who should handle the request – whether it needs proxied to a different CAS, or can be sent directly to an Exchange 2003 or 2007 back-end. For example, when a request is received for the /exchange virtual directory on a mailbox on an Exchange 2003 server, the HTTP request is forwarded to the appropriate server. So in this way, OWA still works from your 2007 CAS – even though the client will see the OWA 2003 interface. The same is true for activesync clients requesting the \Microsoft-Server-ActiveSync vdir.
If an Exchange Web Services call hits an Exchange 2007 CAS and the CAS is able to determine that the mailbox is on an Exchange 2003 back-end the call will fail since proxying cannot be performed.
Here’s more on the topic:
Overview of Exchange Server 2007 CAS Proxying and Redirection
I’ve had a couple cases recently where customers were having problems getting into deadlock with one of our modules, usually MAPI or Outlook. There’s one common thread that connects these cases: message pumps.
Your application has to make a remote call to a server object living in a different process or thread. Often times this is referred to as an “asynchronous” call. That term is somewhat misleading – suggesting your process could actually forget that it made the call and then be surprised when it comes back. In actuality, there’s always a listener constantly waiting for the call to return. What makes it seem asynchronous is that the waiting happens on a different thread. In order to wait for your call return, applications often implement logic called a “message pump.” This just processes incoming Windows messages or RPC calls and dispatches them to be processed; and it keeps processing messages until your call returns.
The problem with this is that there’s no easy way to tell what these incoming messages are or what they’ll do. This is what gets you into trouble.
Let’s say that a normal code path in one thread will go something like this:
There’s nothing wrong with this at all. Everything is fine at this point. Now lets suppose there’s a different thread that does something like this
Now, up to this point there’s nothing wrong. Suppose, however, that one of the pending messages is from Outlook and the execution goes something like this:
Again, nothing is inherently wrong with this execution path by itself. However, when you combine both threads, you have critical sections being locked in reverse order – classic deadlock.
Here’s a way to understand the problem: Let’s say you’re at home watching a Virginia Tech football game (There are other teams? Oh yeah, I just call them “losers.”) with a friend. You both get a hankering for a cold adult beverage. You go to the fridge, but there’s only one left. You decide to split it with your buddy, which is ok, since it’s a 40. Meanwhile, your other friends arrive with their own adult beverages and ask if anyone has an opener. Your buddy gets up and gets the bottle opener. You are thinking, “OK, I have the bottle, now all I need is the bottle opener, but my buddy has it so I’ll just wait until he’s done.” You both return to your respective recliners. Your buddy is thinking, “ok, I have the opener, I guess I’ll just start opening bottles with it until my glass gets filled. Surely one of the bottles will be mine.” As he’s opening your other friends’ bottles, the thought enters his mind – my friend [you] has a bottle he needs opened – I need to get his bottle to open it for him. Since both yours and your buddy’s rear ends are plastered to their respective recliners, you have now entered adult beverage deadlock.
Your buddy was keeping the bottle opener all to himself while waiting for his glass to be filled. Little did he understand that by holding the bottle opener to himself, he was preventing that from happening, since the bottle was already being held firmly in your grip. Had he relinquished control of the bottle opener, you could have easily picked it up and used it. He didn’t know that one of the bottles he had to open would be yours.
So how do we prevent this problem from occurring in the first place? The key is really that your buddy didn’t know what bottles he would be opening, while waiting for his glass to be filled. He didn’t know that you were planning to split the beverage with him. What he could have done is just told your friends that the bottle opener was in the drawer instead of holding onto the bottle opener while waiting for his glass to be filled. That way, when you needed it, it would be available and as long as everyone puts it back when they’re done with it, though you may need to wait for a short time, no one will go thirsty for long.
The moral of the story is that you shouldn’t make it a practice to hold onto a lock while making an RPC call or otherwise pumping messages because you don’t know what messages will arrive in your pump and what locks they will request.
Secondary moral of the story: always make sure your adult beverage supply is properly maintained.