Friday, 7 April 2017

ASP.NET SQL Server: Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.

In an ASP.NET / SQL-Server web app I hit this error in a web form after modifying a the query of a TableAdapter in a .xsd file using VWD:
Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
The underlying SQL Query was a fairly simple UNION ALL query looking for a value (in this case an email address) across several different tables. I had two new tables to search in, so I simply added two more UNION ALL sections to the query for these new tables.

Then I hit the above error. There were some slight differences to the column definitions between the new tables and the existing ones. I tried all sorts of things including CASTing variables and checking for NULLs, all to no avail. Eventually I twigged that it was hanging on to something in the .xsd file behind the scenes.

Solution: Copy the SQL from the table adapter, delete the table adapter, then re-create it and paste in the old SQL. Runs perfectly. (Well, it did after I had two goes at getting the table adapter name exactly the same as before!)

Oh the joys...!

Tuesday, 4 April 2017

"Let your Daemons rest", aka PHP Daemons not sleeping as expected

I was enhancing some inherited PHP code which used the so-called "Daemon Loop" design pattern to read jobs off a queue and hand them off for processing by a configurable number of child worker processes. Specifically, I was trying to get the daemon to wake up once every minute (instead of every 5s) to see it there were any jobs on the queue, so in the loop (in practice the value was read from a config file into a class-level variable), I had:
    sleep(60)

We were also capturing SIGCHLD for notification of when the child closed (in this instance after just a few seconds).

The problem was that the daemon was not waiting 60s to poll unless there was nothing to do. Turns out that SIGCHLD cancels the running sleep(60).

My inelegant solution? sleep(1) 60 times and then only 1s of sleep is lost!
while ($sec>0) {
    sleep(1);
    $sec--;


Thanks to Stuporglue, on whose PHP daemon example code I built a testbed to find a solution.