Thursday, 10 November 2011
Parallel.ForEach operations and the CancellationToken
You could monitor the cancellation token inside the units of work as well if you liked.
Windows Azure DevFabric forcing port 80 rather port 81, 82 etc
Use TCPView from sysinternals and if you find that an item appears under "local port" called "http", then the port is in use. You cannot easily find out what process that is as it's a service, however in my case, once I'd shut down "Web Deployment Agent Service" by doing Run -> CMD -> net stop MsDepSvc this solved the issue and Azure was able to run the web role under port 80.
Also, ensure that Skype doesn't occupy port 80 too.
Tuesday, 25 January 2011
Distributed Lock
I’m working on a distributed system on Azure which has a Web and Worker Roles. Plus, there’s the possibility of N number of instances per role. The Worker role is a batch processor which consists of Jobs and the Job Scheduler. My requirement is that we should only have one instance of the Job Scheduler throughout the whole system.
If this was a simple multi-threaded application with one app domain, this would be relatively simple using a mutex and the lock statement, however, given that the application could be spread across multiple virtual machines within the Azure Fabric I had to come up with another way.
I solved this problem by using a SQL Azure table, serializable transactions and a Distributed Lock Service in C#.
First create the table
/****** Object: Table [dbo].[Lock] Script Date: 01/25/2011 14:18:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Lock](
[id] [int] IDENTITY(1,1) NOT NULL,
[LockName] [nvarchar](4000) NOT NULL,
[AcquirerGuid] [uniqueidentifier] NULL,
[AcquiredDate] [datetime] NULL,
CONSTRAINT [PK_Lock] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
)
GO
Then create the Stored Procedures, “Lock_Acquire” and “Lock_Release”
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Lock_Acquire]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[Lock_Acquire]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[Lock_Acquire]
(
@Name NVARCHAR(4000),
@AcquirerGuid UNIQUEIDENTIFIER
)
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
IF(NOT EXISTS(SELECT 1 FROM Lock WHERE LockName = @Name))
BEGIN
INSERT INTO [Lock] (LockName, AcquiredDate, AcquirerGuid)
VALUES (@Name, GETUTCDATE(), @AcquirerGuid)
END
ELSE
BEGIN
UPDATE L
SET L.AcquiredDate = GETUTCDATE(),
L.AcquirerGuid = @AcquirerGuid
FROM Lock L
WHERE L.LockName = @Name
AND (L.AcquirerGuid = @AcquirerGuid -- owned by the current requestor
OR DATEDIFF(SS, L.AcquiredDate, GETUTCDATE()) > 30) -- or expired so re-assign to new requestor
END
SELECT @@ROWCOUNT;
COMMIT TRANSACTION
END
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Lock_Release]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[Lock_Release]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[Lock_Release]
(
@Name NVARCHAR(4000),
@AcquirerGuid UNIQUEIDENTIFIER
)
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
UPDATE Lock
SET AcquiredDate = NULL,
AcquirerGuid = NULL
WHERE AcquirerGuid = @AcquirerGuid
SELECT @@ROWCOUNT;
END
GO
Import the Stored Procedures into Entity Framework (if you use EF)
Create the Distributed Lock Service
public class DistributedLockService : IDisposable
{
public Guid AcquirerId { get; set; }
public string LockName { get; set; }
public bool LockAcquired { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="lockName"></param>
public DistributedLockService(string lockName)
{
LockName = lockName;
AcquirerId = Guid.NewGuid();
}
/// <summary>
/// Attempts to acquire the named lock
/// </summary>
/// <returns></returns>
public bool Acquire()
{
LockAcquired = Facade.DataContext.Lock_Acquire(LockName, AcquirerId).FirstOrDefault() == 1;
return LockAcquired;
}
/// <summary>
/// Attempts to release the named lock
/// </summary>
/// <returns></returns>
public bool Release()
{
if (LockAcquired) return Facade.DataContext.Lock_Release(LockName, AcquirerId) == 1;
else return true;
}
#region IDisposable Members
public void Dispose()
{
Release();
}
#endregion
}
You may have to change Facade.DataContext to be your equivalent ORM or Sql Helper class.
Create the Unit Test
[TestClass]
public class DistributedLockServiceTest
{
[TestMethod]
public void CheckThatLockingWorks()
{
string fakeLockName = Guid.NewGuid().ToString();
List<bool> results = new List<bool>();
ManualResetEvent handle = new ManualResetEvent(false);
object mutex = new object();
Parallel.Invoke(() =>
{
Parallel.For(0, 100, x =>
{
handle.WaitOne();
DistributedLockService svc = new DistributedLockService(fakeLockName);
lock(mutex) results.Add(svc.Acquire());
});
},
() =>
{
Thread.Sleep(2000);
handle.Set();
});
Assert.AreEqual(1, results.Where(x => x == true).Count(), "The number of trues should be 1 for fake lock: " + fakeLockName);
}
}
Use it for real…
private DistributedLockService _lockService = new DistributedLockService("JobScheduler");
if(_lockService.Acquire()) // do something, like start a JobSo the idea is that you can instantiate the Distributed Lock Service and keep it for as long as necessary, then whenever you wish to perform some action without the possibility of concurrency, do it after acquiring the lock. Please also note that the lock will last for up to 30 seconds at a time, so you must call Acquire within the 30 second period if you wish to retain non-concurrency. Otherwise the lock will be relinquished to any other requestor. If this is too short a timeframe, then you can change it inside the Lock_Acquire stored procedure.
The reason why there’s a time limit is in case the acquiring/lock-owning thread throws an exception and does not release the lock.
Please let me know should you find any problems. thanks.
Monday, 13 September 2010
Dell XPS M1330, nVidia GeForce 8400 GS overheats and the laptop cuts out
I have had this laptop this January 2009 and it’s been fine, but recently it’s been cutting out if I use Google Earth or Bing Maps! I have measured the temperature at which it cuts out is about 110 degrees. When it turns on again, it reports either error #M1001 or #M1004. This is apparently and overheating problem with the nVidia GPU.
I am contacting Dell about this, however my motherboard was only replaced last month when my graphics card failed with what I can only describe as “on screen display corruption issues”. Weird symbols and colours appeared. Oh well, looks like I’ll need another repair, or just have to buy a new laptop as I’m a freelancer, so the loss of earnings will eventually become greater than the cost of a laptop, so I may as well get a new one… hopefully from a more reliable brand.
UPDATE: 15th September 2010: A Dell engineer changed the heat sink and now it runs perfectly!
ASP.NET MVC 2, “Request Validation has detected a potentially dangerous client input value, and processing of the request has been aborted” and the ValidateInput does not work
If you have problems getting the [ValidateInput(false)] attribute to work in a Visual Studio 2010 ASP.NET MVC 2 solution; please remember to put requestValidationMode="2.0" on the httpRuntime element of the web.config.
Then everything will be fine. Enjoy.
Monday, 23 August 2010
Umbraco 4.x – Warning on upgrading document types
Please be aware, though Umbraco is a great Content Management System, once you have deployed an application based on it – it’s very difficult to upgrade items in the meta-database afterwards. Umbraco Courier does a good job of transferring content, but it doesn’t take into account changes to Document, Media and Member types, nor does it take into account new macros or changes to settings on those entities. Courier will report the problems as you try to migrate content which is dependent on a latest meta database changes.
This is akin to developing your database in the development environment, then, once you’ve deployed the software, having to use the SQL Table Designer GUI make all the necessary schema changes manually.
Thursday, 5 August 2010
Dynamic subdomains on Apache and PHP
To rewrite subdomain urls internally to subdirectories under the root, ensure mod_rewrite is installed in Apache. Configure .htaccess inside the root directory as follows:-
RewriteEngine OnRewriteCond %{HTTP_HOST} !^www\.mydomain.comRewriteCond %{HTTP_HOST} ([^.]+)\.mydomain.comRewriteRule ^(.*)$ /home/sites/mydomain.com/public_html/%1/index.html
Obviously replace “mydomain” and change the path on the last line to where your website physically resides on the server. Use the variable %1 to use the name of the subdomain as the name of the destination subdirectory.
Wednesday, 21 July 2010
My iPad Review
I got an iPad a few weeks ago and thought I’d share with you the pros and cons I have discovered:-
Pros
- Great for reading e-books and PDFs
- Makes surfing a web really easy as you can pinch, zoom and scroll really easily using just one or two fingers
- Watching YouTube and videos is a really tactile experience, and so is viewing Photos.
- If you get an iPad you can run both iPhone and iPad apps on it. This is great if you’re a developer and want to target both platforms and not have to purchase an iPhone. For me the cost of getting into iPad and iPhone development has been about £1000 (£500 for the iPad and about £500 for the Mac Mini). Although they have just put up their Mac Mini price. If I’d had to purchase an iPhone as well, the cost would be today at about £1700. I have saved £700!
Cons
- The Apps in the App Store don’t have a trial period, so if you don’t like it, then you can’t get a refund. Also, sometimes the description of an App can exaggerate how good it really is
- Apps can be a bit too expensive
- Re iTunes; I can get the IT Crowd from channel 4 for £10. However, on a Windows PC or a Mac I can go to 4OD on Channel4.com and watch loads of stuff for free.
- No support for Flash, so stuff like 4oD doesn’t work :-( Also, the BBC News website experience is degraded as they rely on flash
- When I download Spotify I find I cannot play music in the background (although this is an iPhone app, maybe an iPad version will be different)
- When I plug in headphones the sound doesn’t seem to come through – not sure whether this is a fault or a configuration problem
- The soft-keyboard is a bit annoying (although, a keyboard or anything other than a proper physical one is generally annoying!)
All in all, if I had £500 to spend and I needed a computer, I’d probably get a netbook and pocket £100-£200. Just because a netbook supports everything and there’s an abundance of free software out there and it’s compatible with most things (e.g. Flash), and it has a regular keyboard so you can work and play on it. Sure, it won’t have integrated 3G, but get a bluetooth link to a 3G-enabled mobile phone and you’re sorted.
Steve Jobs said in his keynote speech, introducing the iPad that it occupies the same market space as netbooks. Although for me, it’s just a different type of device really – and very niche.
In summary then… an iPad is
- Less functional than a netbook (you can literally do anything a PC can do, albeit slower)
- More controlled and regulated by Apple HQ
- However a much more tactile, novel and fun experience
My gut feeling is that, one day, a manufacturer will invent a powerful netbook with a detachable screen and all the fun of an iPad. At least I hope this will happen, alongside a de-facto open e-book format.
Wednesday, 30 June 2010
Get this? Windows Azure MMC, Could not load file or assembly 'Microsoft.Samples.AzureManagementTools.PowerShell, Version=1.1.3779.27370, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
You probably have a previous version of the Windows Azure SDK. Delete all but the latest folder from ‘C:\Program Files\Windows Azure SDK’. For me, I had to delete the folder ‘C:\Program Files\Windows Azure SDK\v1.0’
Thursday, 10 June 2010
Google copies Bing!
One day I woke up to find this atrocity!
And then realised they were trying to do this…
I think maybe Google use Bing.com – which is nice. Well done bing.
Tuesday, 27 April 2010
Escaping javascript strings in Umbraco XSLT macros
How to escape string literals in XSLT which appear inside JavaScript function calls:-
<xsl:variable name="apos">'</xsl:variable><xsl:if test="data[@alias='popupMessage'] != ''"><xsl:attribute name="onclick"><xsl:text>return window.confirm('</xsl:text><xsl:value-of select="umbraco.library:Replace(data[@alias='popupMessage'], $apos, concat('\',$apos))" disable-output-escaping="yes" /><xsl:text>');</xsl:text></xsl:attribute></xsl:if>
Sunday, 25 April 2010
ASP.NET, hMailServer, error “The SMTP server requires a secure connection or the client was not authenticated” or “SMTP authentication is required”
If you receive the above error message when sending email via hMailServer’s SMTP Service, just go into the Admin console –> Settings/Advanced/IP Ranges/My Computer and uncheck the boxes below.
Windows Server 2008, IIS 7, Shared Configuration, System Corrupted Irrecoverably
The story is, I tried to copy IIS7 configuration from one Windows Server 2008 server to another.
- This overwrote the applicationHost.config
- IIS/App Pools failed because global modules that were on the previous server were not installed on the current
- Attempted to install those modules
- that failed.
- Thought I’d try to rollback, but it doesn’t backup the original IIS7 config
- Uninstalled IIS7
- Tried to reinstall IIS7
- That failed
- Tried to set up Windows Installer tracing with special registry entries
- Tracing doesn’t work, no file is output into the %Temp% directory
- Now wanting to do a system restore
- There’s no system restore on Windows Server 2008
Quite a disproportional dilemma given the cause.
I like Microsoft – sometimes. But really, I have had problems with Windows Server set up before… they haven’t put the effort into making this work. And given that it’s usually professionals who are working setting up boxes, it would be a good idea to give some error messages that mean something.
Tuesday, 13 April 2010
Message: Type 'umbraco.DataLayer.SqlHelperException' in Assembly 'umbraco.DataLayer, Version=0.3.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
This is most likely because the database is inaccessible to Umbraco. Check the connection strings are correct and also try connecting using the same connection string credentials with SQL Management Studio.
Friday, 26 March 2010
MSMQ "The destination queue does not exist” or “BadDestinationQueue” when sending MSMQ messages or WCF net.msmq bound service calls
If you’re sending MSMQ messages using the DNS name of the server, you may get one of the above errors… this is easily fixed by adding a new registry key which tells MSMQ to ignore the hostname validation.
- Click Start, click Run, type regedit, and then click OK.
- Locate and then click the following key in the registry:
HKEY_LOCAL_MACHINE\Software\Microsoft\MSMQ\Parameters
- On the Edit menu, point to New, and then click DWORD Value.
- Type IgnoreOSNameValidation, and then press ENTER.
- On the Edit menu, click Modify.
- Type 1, and then click OK.
See the Microsoft Support Article.