|
|
Friday, August 29, 2008
I've maintained that we're hosed, no matter who you vote for, but now there's mathematical proof that regardless of how you vote, you're voting for a white liberal male. Here's the math. 1 Liberal Black Male + 1 Liberal White Male=1 Liberal White Male + 1 Conservative White Female So first, Black Male and White female cancel each other out. They're basically the same thing--both minorities, both oppressed citizens of these united states. That leaves us with: 1 Liberal Black Male + 1 Liberal White Male=1 Liberal White Male + 1 Conservative White Female Of course, 1 Conservative and 1 Liberal cancel each other out, leaving: 1 Liberal Black Male + 1 Liberal White Male=1 Liberal White Male + 1 Conservative White Female And there you have it. 1 liberal white male=1 liberal white male. Now if McCain had been a conservative, you'd be voting for nothing, but as you can see, you're clearly voting for one liberal white male, no matter how you look at the equation. It'll be fun to watch! Now I'm sure this equation could be extended, and I know you might question my math, but I thought it was interesting . . . Technorati Tags: Politics
Friday, August 15, 2008
O.k., I'll admit, the first time that I used windows Vista backup, I was very underwhelmed, but it's grown on me, and now I'm a huge fan. On Monday, I received a new hard drive from Dell. It's bigger and doesn't make strange clicking and stalling noises like the old drive did. :) I was pretty certain that the old drive was going to go. To swap out the drives, I plugged in a USB drive with sufficient capacity and did a windows backup complete pc backup. Once that was finished, I plopped in the new drive and my Vista installation DVD. After the restart, I selected the Restore Vista options, found my complete backup and started the restore. Once it was done, I rebooted and was up and running again. That was it! It just worked! I spent less than 10 minutes (not counting actual backup time) on completely replacing the drive. I've NEVER had a backup and restore go that smoothly. In the past, I've always had to install the OS before I could get to the backup, and then it'd be a hassle because of drivers and such, and the final restore wouldn't quite be the same. This restored things EXACTLY the same. I did have to reauthorize Diskeeper, but that was the only thing that I had to touch. Knowing that I can mount the complete backup using virtual PC is also nice. Technorati Tags: Vista, Backup
Ran into a serialization problem with WCF the other day that was rather interesting to find and fix. It wasn't a problem with WCF, in the end, but rather with what we were telling WCF to do. So we have some complex entities that we're shoving through the serialization layer. We also send through lists of these entities, and the list may have references to itself. To keep our list sizes small, we've implemented a DataContractSerializerOperationBehavior where when we create the data serializer, we set preserve references to true (it's just a variable below, but its set to true elsewhere): private static XmlObjectSerializer CreateDataContractSerializer(Type type, string name, string Notification Services, IList<Type> knownTypes)
{
return new DataContractSerializer
(
type,
name,
Notification Services,
knownTypes,
maxItemsInObjectGraph /*maxItemsInObjectGraph*/,
ignoreExtensionDataObject/*ignoreExtensionDataObject*/,
preserveObjectReferences/*preserveObjectReferences*/,
surrogate/*dataContractSurrogate*/
);
}
To make things more complicated, we have some custom lists of our entities that have properties on them. As you may not know, when serializing a custom collection, the object is treated as a collection and any custom properties are ignored and are not serialized, even if you mark them as a DataMember. Rather annoying. To get around this, we implemented an IDataContractSurrogate, which you can see is passed into the data serializer above. In GetObjectToSerialize method of the surrogate class that we created, we look to see what type we're trying to serialize and if it's one of our custom collections, we create a new instance of a surrogate that has an internal list, but is not a collection class itself, populate it with the contents and properties of the object that is to be serialized and then pass the surrogate back to the serializer. Since our surrogate class is not a collection, WCF detects it correctly and serializes it correctly. Then, on deserialization, we create a new instance of the collection, set it's properties, and then iterate through the surrogate's list and add the items to the new custom collections list.
Everything's happy, right?
Nope. Our custom collection requires that objects of the same type are added to it. The objects themselves have a Name that tells us what they are. Our objects also have children that can be of the same type as the parent and are stored in the same type of class. More precisely: <Set>
<SetItem Name="AParentThing">
<Children>
<Set>
<SetItem Name="AChildThing">
<ParentSetItem ref="AParentThing[0]"></ParentSetItem>
... (Perhaps even more sets and set items)
</SetItem>
</Set>
</Children>
</SetItem>
<SetItem Name="AParentThing">
...(May have many layers)
</SetItem>
</Set>
The problem appeared when we tried to serialize the cases where a child set referred back to a parent set. We were getting weird errors, caused by the constraint that required that all items in a set be of the same type. For some reason, the Name wasn't being serialized, or so we thought. And what was weird is that it worked right most of the time, but then would occasionally fail, and what's worse, if we ignored the error, everything would work like we thought it should. We were sure we'd just found a bug with WCF.
Turns out that name just hadn't YET be serialized.
I'm not sure about the order of serialization with data members, but it appears to be pretty arbitrary, unless you set the order on the data member. We'd done two things incorrectly. 1. We didn't set IsRequired on all of our DataMembers, and since this is a version 1 product, all of our interface elements should be present. In future versions, maybe that'll change, but for now, they should all be there. 2. We assumed that the deserialization of child collections wouldn't happen until after all of the members of the entity containing that collection were serialized, which is not the case. As a result, the collections, which had a reference back to the parent, would attempt to deserialize BEFORE the name property had deserialized.
To fix, we changed all of our data members to look like this: [DataMember(Order=0, IsRequired = true)]
Note that order is 0 based. At first, we only put the order property on the Name element, but that just caused it to fail every time, since WCF appears to serialize everything without an order first, then follow the order priority second. After updating the other methods to also have an order, the problem has disappeared. The name is always serialized first. Note however, that even though the message contains the data, the resulting object may not contain the data.
Fun, Fun, Fun!
Wednesday, July 30, 2008
As a ScrumMaster, these are some of my pet peeves, in no particular order: - Come late to meetings. Better yet, don't show up to the meeting, don't let anyone know that you're going to miss the meeting, and then get grumpy when the ScrumMaster asks you to not do it again. After all, the team doesn't really need to know what you're doing.
- Ignore the priority of stories set by the product owner. He loves not knowing what's going to be completed at the end of the iteration.
- Have side conversations during iteration (sprint) planning, or send chat messages on your computer. Then, when asked a question about what you should have been paying attention to, have a lost look and say, "Could you repeat that," meaning the last 10 minutes of conversation. Rinse, repeat.
- Prefer e-mail for communication. After all, you don't have to bother talking to a human being and you can do nothing while you wait for a reply! Heaven. Why would someone use the phone, an office visit, a chat, screen sharing or any of those other pesky interactive conversation mechanisms.
- Never ask for help, and if you do, make sure you always ask the same team member, even if others might know more. It'll make person your asking much less productive, since he'll have to do your work and his work too! And if you don't ask for help, you can do nothing and blame it on not being up to speed! Teamwork, Shmeemwork.
- Own your stories, and by own, I mean OWN. You touch my story, you die! Then, at the end of the iteration, when you didn't get it completed, make sure they knew it was because you were struggling with a piece of the story. Make sure you don't act like you feel bad to the team or anything, after all, they should have know that you wanted help, even when you told them to mind their own business.
- If you can think of something cool to add, add it now. After all, there's no time like the present! And then, when the team misses the iteration, you can say, "But we have a cool XYZ feature now!" Who cares if you didn't need that feature and it wasn't a priority to the product owner. They'll get over it.
- If you really, really, want a feature to be implemented in iteration, make a defect, and set it to the highest priority available. So what if it's way beyond the scope of what the team committed to do! They'll get over it.
Technorati Tags: Agile, Scrum
Wednesday, July 23, 2008
Read this article today. We've had a couple of bad apples on our team so far, and they caused quite a bit of grief before they were removed. On an agile team, the team can't function if the apples are bad, and a single bad apple can cause much grief for the entire team.
Thursday, July 17, 2008
I've experienced this before, and all you can do is cry. This is why agile is so important. Instead of one person making all of the decisions, you have a team that makes the decisions. The "manager" tends to fall into just a product owner role, which is a good thing. In a team situation, the intern would have had a chance to put out his ideas as to a solution. In agile, they would have been in two to four week intervals, so rather than a 5 month development period, the stakeholders (i.e. the boss) would have seen partial results in a month or less and would have been able to decide if the cost of what was happening was worth it. Probably the team would have concluded that other than a little optimization, the adding of more memory was the best solution. Go Agile, it's worth it.
Wednesday, July 16, 2008
Well, that was certainly annoying. I'm trying to create a new application manifest (deployment manifest), and if I use the -MinVersion (-mv) option as specified in the Mage documentation, it fails with the error, "The minimum version specified is not valid." I'm guessing that this goes hand in hand with the bug that I ran into earlier where you can't do anything but a check after install when using mage. For that defect, I ended up running some code to replace the <expiration maximumAge="0" unit="days" /> tag with <beforeApplicationStartup/>, since mage won't do it correctly. To get around this problem, you end up needing to run mage twice. First, to create the deployment manifest, and second to add the -MinVersion property to the app. Like so (in MSBuild): <Exec WorkingDirectory="$(DeployTempDir)" Command="mage.exe -New Deployment -ToFile MyApp.application -Version $(BuildLabel) -Name "App" -providerUrl https://www.myurl.com/myapp/myapp.application -AppManifest $(BuildLabel)\MyApp.exe.manifest -Install true"></Exec> <Exec WorkingDirectory="$(DeployTempDir)" Command="mage.exe -Update MyApp.application -MinVersion $(BuildLabel)"></Exec> Kinda silly, but it works.
Tuesday, July 08, 2008
Read a great article on how to make agile fail today. Very entertaining and educational!
Thursday, July 03, 2008
Had a problem with WCF that I thought I should blog about. We're in the scenario where we have a WCF service that needs to call another service to do some calculating and then return the result back to the client. For now, the service is hosted on the same server, but eventually, it could get expensive, so we'll push out that calculation to another server. The WCF configuration also has an endpoint address that is not the same as the base address reported to it by IIS; IIS is of course reporting the machine name for the base address. So here's the problem, you'd browse to the service url https://my.url.com/service/service.svc and you'd get the nice service page, but the url for the WSDL would be wrong, it'd be https://servername.anotherurl.com/service/service.svc?wsdl, and when the service would try and call the first url, you'd get weird 404 File Not Found errors, even though you could browse to the service and it'd work fine! Turns out the 404 error was somewhat of a bad error. The file was being found, but the XSD's that were generated were not, because they were at the wrong url. If you clicked on the wsdl location, you'd see urls for https://servername.anotherurl.com/service/service.svc?xsd=xsd0 or something like that. To make matters worse, the ssl certificate didn't match the servername url, which caused problems. I didn't discover this until I tried to run svcutil on the service and came up with: Attempting to download metadata from 'https://my.url.com/service/service.svc?wsdl' using WS-Metadata Exchange or DISCO. Microsoft (R) Service Model Metadata Tool [Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.648] Copyright (c) Microsoft Corporation. All rights reserved. Error: Cannot obtain Metadata from https://my.url.com/service/service.svc?wsdl If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455. WS-Metadata Exchange Error URI: https://my.url.com/service/service.svc?wsdl Metadata contains a reference that cannot be resolved: 'https://my.url.com/service/service.svc?wsdl'. There was no endpoint listening at https://my.url.com/service/service.svc?wsdl that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details. The remote server returned an error: (404) Not Found. HTTP GET Error URI: https://my.url.com/service/service.svc?wsdl The document was understood, but it could not be processed. - The WSDL document contains links that could not be resolved. - There was an error downloading 'https://servername.anotherurl.com/service/service.svc?xsd=xsd0'. - The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. - The remote certificate is invalid according to the validation procedure. After digging forever, I went down the path of seeing if I could modify the base address. Nope, that failed, IIS provides the base address and what you set in the config is ignored. So I tried modifying the behavior to have a specific behavior for this service. That fails, because the URL is then created twice and you'll get an error. Finally, I discovered that you can indeed use host headers on ssl! Following the instructions here, I set the host header and after restarting IIS, the service page displayed the right urls, and the service worked like a charm. You can get the service ID from IIS by clicking the Web Sites folder. Also, the adsutil script is in the AdminScripts folder under inetpub. I also discovered that you can't have more than one host header for IIS or wcf will break. Bummer. You can fix it with an article by Rob Zelt. I don't like how he arbitrarily picks a host header; that seems rather fragile. I'd instead read the base address out of a config file and then iterate through until I found the one that matched (or even just set it without using the passed in host headers at all). Anyway, now I know! Update (7/7/08): You also need to not have a value for the endpoint address. Not sure why, but that seems to make it work. Technorati Tags: WCF, SSL, IIS
Tuesday, July 01, 2008
So Netflix decided that a campaign, by their most loyal customers, to see them destroyed was a bad thing. I got this in my e-mail yesterday: "You spoke, and we listened. We are keeping Profiles. Thank you for all the calls and emails telling us how important Profiles are. We are sorry for any inconvenience we may have caused. We hope the next time you hear from us we will delight, and not disappoint, you. -Your friends at Netflix" They've created a lot of bad blood and mistrust, however. How long before they dump profiles again? If they were to make it so that you can have separate queues per dvd, I'd not care if they dump the profiles, but just taking it away without an option was stupid beyond belief. It's a step in the right direction, Netflix.
|