Can a web service be implemented as a multithreaded Singleton?

  • Thread starter Thread starter Thirsty Traveler
  • Start date Start date
T

Thirsty Traveler

I have a need to implement a webservice where speed is of the essence. This
web service will process product orders in a B2B Extranet scenario where
SLA's are critical, as well as collect metrics on the duration of various
milestones through the application layers path that will be persisted to a
BizTalk 2006 BAM interface for QoS tracking and reporting. Orders not
meeting specified SLA agreements will be automatically cancelled and no
payment received, thus it is in our interest to reduce this as much as
possible.

Because the BAM API call is another path through the layers peripheral to
the order I would like to write the collected metrics to a global
synchronized Queue object and process it out of band via a worker thread
created when the Singleton is instantiated, thus allowing the primary
product order request to finish as quickly as possible. (The worker thread
will consume the Queue and persist the collected metrics, however speed is
not an issue here).

Question: Is this doable?
 
Thirsty said:
I have a need to implement a webservice where speed is of the
essence. This web service will process product orders in a B2B
Extranet scenario where SLA's are critical, as well as collect
metrics on the duration of various milestones through the application
layers path that will be persisted to a BizTalk 2006 BAM interface
for QoS tracking and reporting. Orders not meeting specified SLA
agreements will be automatically cancelled and no payment received,
thus it is in our interest to reduce this as much as possible.

Because the BAM API call is another path through the layers
peripheral to the order I would like to write the collected metrics
to a global synchronized Queue object and process it out of band via
a worker thread created when the Singleton is instantiated, thus
allowing the primary product order request to finish as quickly as
possible. (The worker thread will consume the Queue and persist the
collected metrics, however speed is not an issue here).

Question: Is this doable?

Sure. Are there any particular parts that you're looking for help with?
There's good support in .NET for all of the primitive bits that you'd need
to build this.

Given the kind of application you're describing, I'd think you'd want to
write metrics to something like an MSMQ queue, not just a simple IPC queue,
since then you'd get fault tollerance, crash recovery, and so on "for free"
(of course, nothing's ever free). You could also use a SQL Server table, or
if you're using SQL Server 2005, you could use SQL Server notification
services (son of MSMQ) to queue the message to another process or thread.

-cd
 
Carl Daniel said:
Sure. Are there any particular parts that you're looking for help with?
There's good support in .NET for all of the primitive bits that you'd need
to build this.

Given the kind of application you're describing, I'd think you'd want to
write metrics to something like an MSMQ queue, not just a simple IPC
queue, since then you'd get fault tollerance, crash recovery, and so on
"for free" (of course, nothing's ever free). You could also use a SQL
Server table, or if you're using SQL Server 2005, you could use SQL Server
notification services (son of MSMQ) to queue the message to another
process or thread.

-cd
I thought about using MSMQ. However I have no experience with it. Our web
service is in a DMZ while the business logic and data access layers are
behind the firewall in an internal network. Do you happen to know if this
will pose a problem with MSMQ?
 
Thirsty said:
"Carl Daniel [VC++ MVP]"
Sure. Are there any particular parts that you're looking for help
with? There's good support in .NET for all of the primitive bits
that you'd need to build this.

Given the kind of application you're describing, I'd think you'd
want to write metrics to something like an MSMQ queue, not just a
simple IPC queue, since then you'd get fault tollerance, crash
recovery, and so on "for free" (of course, nothing's ever free). You
could also use a SQL Server table, or if you're using SQL Server
2005, you could use SQL Server notification services (son of MSMQ)
to queue the message to another process or thread.

-cd
I thought about using MSMQ. However I have no experience with it. Our
web service is in a DMZ while the business logic and data access
layers are behind the firewall in an internal network. Do you happen
to know if this will pose a problem with MSMQ?

As long as the necessary ports for MSMQ are opened in the firewall, no
problem. I don't recall which port (or ports) MSMQ uses, but I recall it
being easy to find. There's excellent support for MSMQ in the .NET
framework, so it's really easy to use, too.

-cd
 
Carl Daniel said:
Sure. Are there any particular parts that you're looking for help with?
There's good support in .NET for all of the primitive bits that you'd need
to build this.

Given the kind of application you're describing, I'd think you'd want to
write metrics to something like an MSMQ queue, not just a simple IPC
queue, since then you'd get fault tollerance, crash recovery, and so on
"for free" (of course, nothing's ever free). You could also use a SQL
Server table, or if you're using SQL Server 2005, you could use SQL Server
notification services (son of MSMQ) to queue the message to another
process or thread.

-cd

I am including a sample of what I have in mind if I do it in code rather
than MSMQ. I still have questions on:

1. Garbage collection since this is a web service. Will it only occur on
server reboot?
2. How should I control the thread. Should it just loop until the server is
rebooted as well?
3. Do I need a lock on the Queue object or is it enherintly threadsafe for
enqueue/dequeue?

CODE SAMPLE

[WebService(Namespace = "http://mycompany.com/b2bTestservices")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class TestServices : System.Web.Services.WebService
{
Queue<TestTxnMetrics> metricsQueue = new Queue<TestTxnMetrics>();

static readonly TestServices instance = new TestServices(); public
static TestServices Instance { get { return instance; } }
static TestServices() { }

TestServices()
{
Thread thread = new Thread(new ThreadStart(UpdateTestBAM));
thread.Name = string.Format("UpdateTestBAM{0}", 0);
thread.Start();
}

[WebMethod]
public XmlDocument OrderTestCert(XmlDocument doc)
{
TestTxnMetrics metrics = new TestTxnMetrics();
metrics.TxnStart = DateTime.Now;

ITestOrder rObj =
(ITestOrder)Activator.GetObject(typeof(ITestOrder),
ConfigurationManager.AppSettings["TestRemotingServer"]);

string ret = rObj.PlaceTestOrder(doc.InnerXml, metrics);

XmlDocument retxml = new XmlDocument();
retxml.InnerXml = ret;

metrics.TxnEnd = DateTime.Now;
lock (this) { metricsQueue.Enqueue(metrics); }

return retxml;
}

private void UpdateTestBAM()
{
//loop this and sleep between loops. but how do I terminate it?
FloodTxnMetrics metrics = metricsQueue.Dequeue();
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top