Ayende @ Rahien

Refunds available at head office

Functional Longing

I am reading the Erlang book right now (post coming as soon as I finish it), but so far I have managed to grasp the idea of heavy use of recursion and functions for everything. It is very different from imperative languages, but I think I can make the shift.

Joe Functional, however, may have some trouble on the other way around. The following were found on production (but I'll not comment any further on their origin):

public static int CharCount(string strSource, string strToCount, bool IgnoreCase)
{
    if (IgnoreCase)
    {
        return CharCount(strSource.ToLower(), strToCount.ToLower(), true);
    }
    return CharCount(strSource, strToCount, false);
}

Let us ignore the inconsistent naming convention, the misleading function name are really think what this does...

public static string ToSingleSpace(string strParam)
{
    int index = strParam.IndexOf("  ");
    if (index == -1)
    {
        return strParam;
    }
    return ToSingleSpace(strParam.Substring(0, index) + strParam.Substring(index + 1));
}

The pattern continue, but at least I can hazard a guess about what this does, but I wouldn't want to pipe this post through it.

public static string Reverse(string strParam)
{
    if ((strParam.Length != 1) && (strParam.Length != 0))
    {
        return (Reverse(strParam.Substring(1)) + strParam.Substring(0, 1));
    }
    return strParam;
}

"Reverse a string" is something that I like to ask in interviews, but I don't suppose that this implementation will be found sufficient.

Ayende.WTF?!


I have a confession to make, I just finished writing a method with 28 local parameters.
After refactoring, it turned out to be five methods and the main one only has "only" 8 local variables, whew.

Babylon == Spyware: The WTF doesn't end!

As I said, after the email exchange with Babylon, I was left with a sour taste regarding them. I have restored my key from a backup, and I have put the episode behind me, until a few minutes ago, when I go this dialog on my system. I was shocked, because I couldn't believe that someone like Babylon would get to these kind of tactics.

As you can see (the dialog below), I am a registered  user, so it is not "reminding" me that I need to register. This is an invasive advertising on my desktop and without my permission! 

image

There is a word for that, and that is called a spyware! 

You may notice the link at the bottom of the dialog, where it says that I can opt out by going to their site. I did, and it too me here (with a bunch of query strings that I stripped) where it asked me for a CATPCHA to un-register from this!

 WTF!?!?!

image

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.

Babylon: Still not getting how to treat customers

Just got (after three weeks) a response to my issue with them:

The confirmation letter you received initially displayed this message : "This page is your proof of purchase. Please print and save it for future reference."
 
The responsibility of keeping track of your license details is yours.
 
Keeping track of user license  and hosting it in our data base, consumes a lot of storage space, and demands the attention of a large crew of people, dealing with both software and hardware, and as I wrote before, this task is not free of charge.

So, basically they are saying it is my fault (correct) and that I should deal with it (wrong). I am talking wrong in making me a happy customer. Every other company that I did business with was more than happy to resend me the license details, sometimes several years after the fact. The fact that Babylon is treating a customer like this is amazing.

Hiding behind "it cost a lot of money" is a sad excuse for someone who know how this stuff works. My response:

I am aware of that, but you know what, that is not a nice way of getting repeated business.
And don't try to tell me that keep the user data cost a lot of money that you wouldn't spend anyway.
Frankly, I expect response times that are greater than three weeks and a far more civil treatment as a paying customer.

 

 

Web Forms are killing me

I would preface by saying that I am using Web Forms at my current project because the client insisted. They are paying, they get to make the decisions, end of story.

This is a rant, plain and simple. I don't do those often, but I have too much annoyances lately to not do it.

I have several years of working with Web Forms, in projects of various sizes, I have committed my Sins Against the GridView, and have memorized the page lifecycle, I have walked the path of Page.ProcessRequest, and learnt at a distant monastery about the mysteries of the ViewState, I have studied the intricate play of control's events and the secrets of Data Binding.

I get Web Forms. I know how they work.

I have detailed elsewhere what I don't like about WebForms (trying to be stateful, complex, lying, etc). Today it had gotten to the point when I have given up on trying anymore. This was after we have been hitting, repeatedly, obstacle after obstacle with using Web Forms.

Today we had no less than three such incidents, all of them related to various intricate ways that the whole messy pipeline is working together to create a results that is more complex than the sum of all its parts and the legacy systems on the next door. Today was far from being an exception.

We didn't even try to do anything complex. Take a bunch of objects, bind them to a GridView, rinse-repeat. There was a set of pages that were almost literally forms over data, exactly the use case for WebForms, or so I have thought. In a set of about a dozen pages, with really minor differences between one another, we had at least one serious problem at each page. Invariably it was related to some weird way WebForms expected me to work.

In order to get the data from the request, I need to bind the data again in page load, and in a later event, I need to process it, after the Web Forms engine had magically filled the values from the request. And woe upon you if you dare to mix a data source with a call to this.DataBind(); for you are heretic and deserve to lose the user's input without warning, and only by the grace of the good lord will you be saved.

At one point today I resorted to an http handler and a set of calls to Response.Writer(), because that was easier than trying to get the functionality from the WebForms engine.

At this point, I feel like I am trying to build on top of a house of cards, with the slightest movement will send everything crumbling down. I found a bug that was totally my fault today, and we had about five minutes of hilarity about finally finding something that we could easily fix. While this is a very instructive in terms of knowing how the internals of the WebForms engine works, it is a complete waste of time otherwise. When I need to be absolutely aware, at all times, about all the implications of what is going on all around me, I can't really do anything at all.

I have learned my lessons from past projects, thou shall not try to be smart with the WebForms framework, it will be smart right back at you and bit you in the ass. I am not trying to do anything smart here. I am literally scaling down everything that I do on the UI layer to the set of what is wholly approved and blessed by Microsoft. I am not even trying to workaround technical limitation, I am just trying to build working software.

At this point, I am more willing to debug Dynamic Proxy's IL generation engine than my pages, because at least with Dynamic Proxy, I have some control over what is going on, hard as it may be. The WebForms engine gives the illusion of control, but it does things in completely arbitrary ways, contrary to the principal of least surprised and common sense.

I am sick of it.

At what point do you say WTF?! Runtime addition of methods to class in C#

Assume that I have this piece of code: 
public interface InterfaceWithExplicitImpl<T>
{
   IEnumerator<T> GetEnum1();
}
Now, check the picture. This is 100% repreducable, but only under very specific set of scenarios (basically, running System.Reflection.Emit stuff). I am not sure how exactly I am supposed to handle this sort of an issue.
 
WTF
 
Here is the code to repreduce the issue:
You need to reference Dynamic Proxy 2, but this code produce stuff that I would bet is flat out impossible.
 
   1:   class Program
   2:   {
   3:       static void Main(string[] args)
   4:       {
   5:           Console.WriteLine("Before it has {0} methods", typeof(MyInterfaceWithExplicitImpl<int>).GetMethods().Length);
   6:           
   7:           ProxyGenerator generator = new ProxyGenerator(new PersistentProxyBuilder());
   8:           generator.CreateInterfaceProxyWithoutTarget(typeof(MyInterfaceWithExplicitImpl<int>), new StandardInterceptor());
   9:           generator = new ProxyGenerator(new PersistentProxyBuilder());
  10:           generator.CreateInterfaceProxyWithoutTarget(typeof(MyGenericInterface<object>),
  11:                                                           new Type[] { typeof(MyInterfaceWithExplicitImpl<int>) },
  12:                                                           new StandardInterceptor());
  13:   
  14:   
  15:           Console.WriteLine("After it has {0} methods", typeof(MyInterfaceWithExplicitImpl<int>).GetMethods().Length);
  16:       }
  17:   }
  18:   
  19:   public interface MyInterfaceWithExplicitImpl<T>
  20:   {
  21:       IEnumerator<T> GetEnum1();
  22:   }
  23:   
  24:   public interface MyGenericInterface<T> where T : new()
  25:   {
  26:       T DoSomething(T t);
  27:   }

Live Spaces: Not for FireFox

I just tried to visit this URL: http://pauloquicoli.spaces.live.com/Blog/ in FireFox, I get this message:

Sorry, we are unable to complete your task at this time. The Windows Live Spaces service is experiencing difficulties. Please try your task again later.

In IE, it works as expected. WTF?!

Update:

Looks like this was the issue, I had this cookie
Name: sc_stgclstbl_107
Value:
YjdmOTYxYjQyMjYyNWJkZjE6Rzk2bmRvVzA3WlF6UldO
YlZiNWpnZC9uSkZ2SzVhWHRkSW9iK2RR
T3E4R2lTbUM4cytUSGdKUFZNaVJpY2tkSTYrZC9takRvc09RPQ

The value is not valid base64, appernatly, which is what caused the issue.

For Experts Only

There are some things that programmers really shouldn't do. I was once called to help figuring out why a batch process would run for a few hours at 100%. The previous guy has claimed that this was a natural occurance of the task at hand (loading XML file to DB), and that he had already optimized it as far as possible.

int count = 0;
XmlDocument xdoc = new XmlDocument();
xdoc.Load(filePath);

foreach(XmlNode node in xdoc.SelectNodes("data/row")) 
{
   count++;
   new Thread(delegate(object state){
        XmlNode n = (XmlNode)state;
        using(SqlConnection con = new SqlConnection("... "))
        using(SqlCommand cmd = con.CreateCommand ())
        {
            cmd.CommandText = "INSERT INTO .... ";
            cmd.ExecuteNonQuery();
        }
        Interlocked.Decrement(out count);
   }).Start(node);
}

while(count!=0); 

After de-optimizing the code, I managed to get 10,000% performance improvement, and you could actually use the server for more than a single task.

A business plan more stupid than the RIAA

I thought that after the "let us sue all our customer" business plans, there couldn't be much worse, but Media Rights Technologies has proven that it can top that, with a business strategy that consist of "let use sue anyone who isn't a customer, on the charge that he isn't a customer.

 

Tags:

Published at

SSIS: I know better than you do

If you haven't guess it by now, I am not fond of SSIS. The latest installment is probably a "feature". Assume the following, I develop an SSIS package on my local machine, testing it against a local database.

Now, I want to run the package against a remote database. I did the Right Thing and put the connection string in a data source, so I change that and run the package from Visual Studio. Imagine my surprise when Visual Studio does a full cycle, including reporting the number of rows that it copied. Everything seems to be fine, until I checked the database itself.

About half the tables where empty, and I am still not sure why. The best guess that I can make is that it is caching the previous database credentials, and writing to that, since I found the data in the local database. Argh!!

SSIS: You really don't need all this data

Here is SSIS deciding that "No, you really don't need to move this data."

NoNeedForThatData.png

I really like the "smarts" that went into that engine. I make sure that I keep busy and don't move on to othe areas of the application, but dedicate my full an undivided attention to SSIS, as it is apperantly should be.

Would it be too hard to provide a deteministic engine? SSIS would run only (random) parts of the sequence container if I right click it and tell it to "Execute Container". Doing a full debug seems to work, but it execute stuff that I don't want to run right now. Urgh!

Host review: Webhosting4life, Recommendation: AVOID

I am posting this because I am extremely annoyed. I moved from my previous host because of reliability issues, I had to do it fairly quickly, so I didn't have time to really ask around and find out the best host. I went to webhosting4life because it was fast to setup, and I believed that they were big enough to be competent.

(Image from clipboard).png

I do not have a very big site, or a very complex setup, I run two applications, one needing MySQL, the other needing SQL Server. Neither of which is particularily tasking on the server.

As you can see, I had 6 outages in the last 20 days, some of them lasting mutliply hours. In nearly all cases, the reason that I was given was:

There is a routing issue on that server. Our tech is working on it now.

I could accpet it once or twice, but when it go to this level... below is a chat transcript of me and a tech from webhosting4life. It is complete with spelling mistakes and everything. As a result of this, and the evasive answers that I got, I am now on the lookup for a new host.

Notice that the operator simply left the chat when I tried to get additional information about the root cause of the problem. The chat equilent of hanging in my face! They have "Email our CEO" link on the help desk page, which I used to send a question regarding the frequent outages, I never even got a "Thank you for email us".

Powered by SightMax
Welcome to sightmax2.webhost4life.com. alvin will be right with you.
alvin
hello
Ayende Rahien
my database is down
Ayende Rahien
http://www.ayende.com/Blog/
Ayende Rahien
An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
alvin
could you please let me have a check.
Ayende Rahien
yes
alvin
There is a routing issue on that server. Our tech is working on it now.
alvin
Could you please check it out later? If it still have problem. please open a urgent ticket in our helpdesk system. Thanks.
Ayende Rahien
This is the 5th time that I heard about a routing issue with the servers.
Ayende Rahien
Each of those time, it was because I had noticed that my site was down!
Ayende Rahien
That is not an acceptable way of hosting.
alvin
I am sorry about this, we are working on the issue now. Thanks.
Ayende Rahien
How can I get an answer from an authorized source about this issues?
Ayende Rahien
I would like to know what it the underlying reason for the frequent outages and the actions taken to fix this.
alvin
Could you please open a ticket about this issue, and our senior tech will give more details to you. Thanks.
Ayende Rahien
304056
Ayende Rahien
I did
Ayende Rahien
How can I get guarantees about uptime?
Ayende Rahien
I am not expecting five nines, but I do expect more than 80%
Ayende Rahien
Hello??
alvin
Dear customer, it seems that there is a routing issue on the network that make the connection for your site can't connect to the database. Our technician are working on the issue now. Sorry for any inconveniences caused. If you want a quick fix, please change the connection string to IP first.
Ayende Rahien
Nice copy/past.
Ayende Rahien
Now, can you tell me why you are recommending that I would do something that you explicitly tell me NOT to do on your site?
Ayende Rahien
It concerns me that there is a canned response for this question.
alvin
As there a routing issue in the data center, and can let the web servers to reslove the domain name, and the quick fix is using IP to instead.
Ayende Rahien
And why does it occur every other day?
Ayende Rahien
I cam to you because you were supposed to be a proffesional hosting service, with good technicians that would NOT mess the routing in the data server every day
alvin was removed from the chat.
alvin has terminated the chat session.

 

I miss my compiler

I am starting to get that C++ feeling back. Check this out:

(Image from clipboard).png

Valid, PEVerified, executing just fine. The fact that it is also very very wrong seems to go by the CLR without notice. In case you are wonderring, what the AddValue method gets is: 20872412, or maybe a better way to put it is: 0x13E7CDC

 

Tags:

Published at

More code generation mysteries

This actually run just fine, it even passes PEVerify, for somet reason:

(Image from clipboard).png

Naturally, this causes issues, but only when you are doing cross app-domain stuff.

Team Foundation Scalability ??? And why CodePlex exists?

I got a comment from Jonathan Wanagel on my CodePlex WTF. I complained that I couldn't get an access to source via Team System. I do not consider tarballs to be a good way of getting source for projects that I may be interested at. There is too much stuff that I cannot do that I should be able to (diff, reverts, easy update to new revision, patches, etc).

Here is the comment:

Unfortunately TFS isn't scalable enough to support all the anonymous users on CodePlex, so we restrict SCC access to project team members only. We're investigating ways to get around this.

I am not quite sure what I am supposed to think about this. The cheeky answer is: Well, Subversion can.

Note: It is probably a lot easier to scale a Subversion farm than a TFS farm, because of the wildly different architecture choices made. TFS depends on SQL Server, which is complex to setup for thousands of concurrent users, Subversion is much simpler in this regard.

Let me run by that again, CodePlex is supposed to be an Open Source hosting site, but it doesn't let me access the source in an acceptable way, it doesn't let me create patches easily, it doesn't work.

I have an OSS project on the side that I don't even try to gather community around (Rhino Tools), so far I have gotten several dozens patches (99% of them accepted), because the source was there, it was easy to access, it was easy to modify and then send the patch to me to merge it in. I seriously fail to see the value that CodePlex can provide an Open Source project.

You may think that this is a minor matter, but I consider this a make-or-break point.

Visual Studio SP1: Hosed My Machine

I started to get this types of errors all over the place after the SP install rolled back. Googling the results, is looks that I am not the only one with the problem, and there doesn't seem to be a solution in sight.

(Image from clipboard).png

WTF!

Just to remind you, this is the RTM version of the SP1 that I tried to install

I did not write that code!

(Image from clipboard).png

I have no idea what happened, but I was working on an ASP.Net application (no un-managed code), hit the pause button in the debug menu, to see where the application is spending a lot of time, and I somehow ended up here. Hm... somehow I get the feeling that my team didn't write it...

Tags:

Published at

MS Consulting and The Client's Best Interest

Karl Seguin has posted MS Consulting : One Consulting Company To Rule Them All, which I read with a sense of sinking horror.

The problem with software consulting firms is that their incentives likely don't line up with their client's...

[some paragraphs talking about how a consulting company can screw their clients...]

Enter Microsoft.

Assuming we are strictly talking about Microsoft technologies, Microsoft is best positioned to solve the problem.

I work in a consulting company (which is also a Microsoft Gold Partner) so I am probably biased.

Karl then goes on to the really big issue with this suggestion:

Of course, there are flaws with my approach. First, it assumes that Microsoft Consulting is able to deliver quality products, hire quality developers and properly manage them. ... Consultants would likely be pressured to push Microsoft technologies that really aren't necessary (i.e, build something for InfoPath and require the company to buy 3000 copies of the program).

I can speak from second-hand experiance with having to deal with MS consultant "advice". It consist of "use [only] Microsoft products". I recently had to battle against using SharePoint and BizTalk in a project where they are completely the wrong tools for the job. And I had to explain to management (about 9 months ago) that no, using DLinq is not going to be a viable solution for a long time yet, because a MS Consultant told them that this is the One Microsoft Way to do data access from now on.

I have a big problem with the tendecy to go with all Microsoft (and only Microsoft) solution when there are often better alternatives around. I have yet to find the Microsoft consultant that will prefer using NUnit to MS Test, depsite some serious flaws in MS Test, for instance. Or suggest using log4net instead of bringing the who EntLib to a project (thereby increasing the complexity of configuration alone by an order of magnitude).

There are some crappy consulting firms out there, one of the thing that We! does is to provide code review services for companies that wants an independent review of the product that they are getting. Some of the code that I have had to go through is so nasty it is in the monthly WTF zone. Here is an actual quote from one of the mails I had after I did a performance review on a system:

The author of this piece of code has managed to achieve the unique state of being able to go very deep into the framework, while combining absulote cluelessness of the reasons why [a problem] occured. I have to say that I am impressed with the ability to dig so deeply to find the core issue, and amazed that at the same time, he managed to so completely missed the target. This code manages to be both ugly to use and the most inefficent way to do [a particular thing] that I have yet to see. All points for inventiveness, zero points for thinking.

I recognize that getting really bad products from consulting company is something that is not that rare. There are better ways to handle this than to trust that Microsoft would do a better job. The more likely scenario is that you would start spending a lot more money of licenses (and training/consulting about how to configure/administer/manage your new software) than before.

I currently have a system in production that is using SQL Express, preciesly because the data the application is managing is small, and can be purged on a regular basis. This meant a drop of $6,000(!) in the project price. What do you think a MS Consultant would have choosen? Would it have served the client's interest better?

Karl suggests that it is easier for the customer to detect a sell pitch in the style of "you should use BizTalk" than to spot getting a really crappy product. I would say that the reverse is true. If a manager is unable to have independant code reviews, or unwilling to head their advice, there is no gurantee that they will be able to understand whatever BizTalk (or SharePoint, or MS CMS, or the like) is a good solution for the problem at hand.

I personally know of at least one BizTalk installation that I could replace with about three days of work, and get more maintainable code, better scalability, far better robustness, etc. In that case, the client certainly hasn't benefit from what BizTalk has to offer.

I can tell you that I (and We!) take a great deal of pride in what I create. I tend to not ship crappy code on a aesthetic basis. I had to go back to old projects, for code harvesting, additional development, bug fixes, etc. Producing crappy code means that I go home depressed, and I intend to do "this computers stuff" for a long time.

The core problem still exists, of course. One of the solutions is to have someone from the client side (either in-house or a third party) review the code and make sure that it matches the required standards. In most of my there is such a person, and it is my responabilities to walk them through the code and explain stuff (and have heated arguments ;-) ). The other is to have some sort of a support contract, which may include some clauses about fixing bugs in the application, acceptance tests, etc.

To sum it up, I think that it is a naive approach at best.

Note To Google: Outsourcing Support to Mail Daemon - Not Good Idea

So, I have trouble with my adsense account, I am doing the right thing by hitting the support pages and actually reading them, but they aren't helping my issue. Therefor, I decide to contact Google's support. I use their own support page, and send an email.

(Image from clipboard).png

I was surprised to get a response almost immediately, the problem is that I wasn't pleased with their message...

(Image from clipboard).png

WTF?!?!?!

Tags:

Published at

Stand back, I am Certified!

(Image from clipboard).png

I just took 070-315 MCP test. Frankly, I was appalled by the level of questions that they had there. I speak here as both a technical guy and as a teacher. I used to be responsible for teaching and educating, and I am familiar with the concepts of good tests.

If I was handed this test for evaluation, even without the technical knowledge to judge the questions, I would have failed it. And question that has the following as answers is fatally flawed...

A) products.Merge(otherProducts, true);
B) products.Merge(otherProducts, false);

And that is leaving aside my own feeling about my own feeling about the whole DataSet / DataTable issue. Asking about the specifics of API in this manner is simply wrong. Especially when it is a boolean parameter. What are they testing, exactly?

Another question had the following query:

"select * from Users where UserId = " + userId

And the correct answer was something along the lines of:

dr.GetInt32(0);

I have so many issues with both question and answer that I don't know even where to begin. Given that I wouldn't hire anyone who tried to give me this code as an answer to a question, I have a lot of issues with this being a question.

Just a few notes:

  • Concatenating strings to create queries.
  • Not using parameterized queries.
  • Using raw numeric indexers to get the data from the query
  • Relying on the DB orderring of the columns.

I never had that much respect for certifications in the first place, but this is really pushing it. If this is the level of the tests, I am going to start putting job ads that says: "Not certified by Microsoft - BIG Plus."

Interesting deprecation approach

Found on the SQLite site:

This pragma was available in version 2.8 but was removed in version 3.0. It is a dangerous pragma whose use is discouraged. To help dissuide users of version 2.8 from employing this pragma, the documentation will not tell you what it does.

That is an... interesting way to go about deprecating features.

Tags:

Published at