No Category
While looking for a URL rewriting tool for a client I found a reference to a tool, clicked the link and got a 404 error.
There is an article in Dr. Dobbs that describes a survey performed by the author. The survey was intended to query Project Managers, IT Managers, IT staff and business stakeholders on what defined the success of a project.
There were definitely some interesting findings:
- The IT industry has a long way to go to achieve a 100% success rate for projects
- Agile projects were more successful than traditional waterfall projects
- Off-shored projects were most likely to fail
- Respondents rated quality as the most important issue, and rated the importance of following items this way when analyzed as a group:
Quality > Scope > Staff Health > Time of Completion > Money
- Project managers differed significantly from all other groups in their perception of success, rating time and money over quality.
- Business stakeholders placed a higher value on ROI and and shipping when ready than the rest of the groups
- A majority of respondents in all groups worked on projects they knew would fail from the start, but canceling a troubled project was not viewed as a successful outcome
I am not surprised by project managers having a different view, given that they are trained to value on-time and on-budget projects. Someone has to keep an eye on the bottom line, but I have experienced this gap when a project runs into trouble. I have been thinking about the differences between Agile and Waterfall-style projects and how they differ. I think there is some middle ground between the two that is yet to be identified that gives us the benefits of heavier requirements and design and the responsiveness to change.
Got my new November Dr. Dobbs issue today. The back column "Swaine's Flames" has reminded me of some programming "laws" that I have seen before. I have added my own corollaries for each:
Kernighan's Law: "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."
My corollary: "The developer who's code that you inherit believed they were twice as smart as they really are."
Eagleson's Law: "Any code of your own that you haven't looked at for six or more months might as well have been written by someone else."
My corollary: "You can recognize that you have written code to solve a particular problem but will be unable to locate the specific instance you recall."
Sometimes when copying databases, for instance from production down to development, the user accounts become dysfunctional. The database login no longer matches the overall server login. To re-synchronize them use:
exec sp_change_users_login auto_fix, 'someusername'
We all spend lots of time delving into the technical aspects of our work, but don't forget who we are creating all these wonderful apps for. You need to design your apps to work for the users, not create apps that the users need to work to use.
Required Reading: Four Modes of Seeking Information and How to Design for Them
I needed to create a publisher for exceptions to a text file (XML would be better but the requirement was for text...). I based my publisher on this article I found on C# Corner. But it has one problem associated with using files, that unfortunately loomed large. Concurrency. To a certain extent the code handled the problem by tossing the error into the Event Log if the provider threw an error, but this was not acceptable for my requriement. So I needed to modify the code to handle the issue. Essentially, I modified the overriden Publish procedure to trap the error related to the StreamWriter and then sleep for a set amount of time and try again. After too many failures at writing to the file the error eventually gets written to the event log (so it is not lost).
privateconst int WriteAttempts = 5;
private const int SleepTime = 500;
void IExceptionPublisher.Publish(Exception exception, NameValueCollection additionalInfo, NameValueCollection configSettings)
{
// Read and set up configuration
SetConfig(configSettings);
// Create fileName
string logFilePath = CreateLogFilePath();
// Create Message
string logMessage = CreateLogMessage(exception, additionalInfo);
int attempts = 0;
bool written = false;
// Write the entry to the log file.
while(!written && attempts <= WriteAttempts)
{
try
{
// Append to file if exists or create new file
using ( FileStream fs = File.Open(logFilePath, FileMode.Append,FileAccess.Write))
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(logMessage);
written = true;
}
}
}
catch
{
attempts++;
Thread.Sleep(SleepTime);
}
}
if(attempts > WriteAttempts)
{
throw(exception);
}
}
A recent post by Lamont Harrington asks about the proper methods for exception handling:
“Should exceptions be bubbled up the call stack and be unwound by a “global“ exception handling layer and logged appropriately, or should some form of exception handling happen at the point of code execution? “
I think a proper design does both. There are cases where the exception can be handled in the procedure where it occurs. Good defensive coding trys to identify as many of those cases as possible and handle them (Actually, good requirements and design should identify many of these situations). Obviously, you cannot foresee all circumstances so the “global” handling is necessary as well. Personally, I don't like to repeatedly re-throw an exception up the call stack because the procedures don't handle it specifically, I would rather let it bubble up on its own and handle it at the end. Re-throwing tends to bury the real source of the error when you are trying to debug a problem in a multi-tier application.
I have to add a plug for the Exception Managment application block. It has been very good to me so far.
I recently changed companies, and am now in the second day of my new job. Today I actually got to write code, fixing bugs in a project that is nearing the end, almost ready to move to QA. It's quite exciting at a new place with the new people and the positive potential. I've even already learned some new things, I expect it will keep going that way.
When I took this job almost four years ago, one of my main motivations was to no longer be a one man shop. Well, a rough time for the automotive industry has me back in that position again. In the middle of December the only remaining member of my team (other than me) was laid off. Now I am a one man shop once again. It's a big change in coding and testing. I am now realizing how much I relied on my team members for cross-testing my code. It is much more difficult to get the same results myself. I am also missing the second opinion that I didn't realize I was utilizing so much.
Unlike my previous job, there are other programmers in the department, so I am not completely alone. The other developers are not very familiar with my project though and can't be of much help. But at least there is still some camaraderie.
Our application uses some fairly complex PL/SQL procedures to build reports in temporary tables so that we can access the data as a ref cursor and bind to a grid. We built the tables using “on commit delete rows” when creating the Oracle table. See DBASupport.com for a quick explanation of Oracle's temporary tables. But calling commit inside the PL/SQL package did not delete the rows as implied by the Oracle documentation. The new data on subsequent calls simply added to what already existed in the table. We are using an Oracle Provider version of the Data Access Application Block, and called the stored procedure like this:
DataResults = Daab.ExecuteDataTable(CommandType.StoredProcedure, ProcName, ProcParametersArray)
To solve the problem, we wrapped the call to the stored procedure in a transaction, even though the procedure only issued select sql statements.
Dim FakeTransaction As OracleTransaction
FakeTransaction = Conn.BeginTransaction(IsolationLevel.Serializable)
DataResults = Daab.ExecuteDataTable(FakeTransaction, CommandType.StoredProcedure, ProcName, ProcParameters)
FakeTransaction.Rollback()
Oddly enough, calling .Commit() did not work as implied by the “on commit delete rows“ command added when creating the table. The data persisted in the table. Calling .Rollback() worked though, as I would expect for any transaction. I was unable to find documentation to tell if there is any perfomance drawback to using IsolationLevel.Serializable versus IsolationLevel.ReadCommitted or IsolationLevel.Unspecified as all three give the desired effect on the temporary table.
The October issue of Dr. Dobbs Journal has a small article called Quantifying Popular Programming Languages. This article is unfortunately not available on-line for free. Dr. Dobbs surveyed web-based job boards to see what percent of the job postings contained references to specific programming languages, but they did not divulge which boards they surveyed. The survey lasted from July 2002 to June 2003. Only 16.4% of the jobs posted contained references to .Net, 5.35% mentioned VB.Net specifically, and 5.16% mentioned C#. Java ocurred in over 40% of the ads and C++ was in over 50% of the ads. Visual Basic was in 19.2% of the ads. Does this reflect a slow adoption of .Net? Or is this just an effect of the economy, or both? I have lurked around the MCAD usenet group and seen frequent comments about the lack of jobs specfically for .Net. Of course, my company is certainly not hiring (see my post here), and the project I am on is the only .Net project in the company. In my experience the benefits of .Net development are significant compared to what we were doing in the past, even for the customer. Are we just not getting through to the business decision-makers about where we need to go? Or should I really spend more time learning C++?
My company just spent 3 days laying off tons of people. I survived this round, but the development group I am a part of lost three people. The company was about 8000 people worldwide, I wonder what it is now. Managment is not interested in distributing the details. It's pretty rough watching the CIO follow around the HR team that is laying people off, and then getting to listem to them cleaning out the cube on other side of the wall. I am fortunate to have a good project that lets me learn .Net. If my turn comes at least I am acquiring new skills.