Remoting for shared access

J

John Bailo

As far as I can tell, there is no way in a Web service, per se, to have
a truly shared object or resource such as a file...one that I can manage
multiple updates on with a mutex for both reading and writing.

Therefore, I think I should use a Remoted service that manages calls to
the file, with a mutex. I would then call the Remoted service from the
web service calls.

Thoughts?
 
N

Nicholas Paldino [.NET/C# MVP]

John,

I don't know if this is the best thing to do. Considering the potential
volume for accessing this, a mutex would be a performance killer.

If this is not an issue, then I don't see why you can't use a mutex in a
web service. You just should make sure that you use a named mutex? I mean,
what else would stop you from using that?

Hope this helps.
 
J

John Bailo

Nicholas said:
John,

I don't know if this is the best thing to do. Considering the potential
volume for accessing this, a mutex would be a performance killer.

If this is not an issue, then I don't see why you can't use a mutex in a
web service. You just should make sure that you use a named mutex? I mean,
what else would stop you from using that?

I understand how to set up a mutex on a file, but how do I create say a
global object, such as file, that all instances of the web service can
access without collisions ?
 
N

Nicholas Paldino [.NET/C# MVP]

John,

You would create a static property in that case. As long as they are in
the same app domain (and they should be), they should all hit the same
instance.
 
J

John Bailo

Nicholas said:
John,

You would create a static property in that case. As long as they are in
the same app domain (and they should be), they should all hit the same
instance.

Sweet.

So I could define a file object as a static property of the web service
class.

Then I could restict access to it with a named mutex ( would the mutex
be a static property as well ? ) so that multiple calls to the shared
resource would be managed.

Right ?
 
J

John Bailo

Nicholas said:
John,

You would create a static property in that case. As long as they are in
the same app domain (and they should be), they should all hit the same
instance.

Are you saying that all clients access the same instance of a web
service -- and its associated methods ?

I thought that each call to a web service or web method instantiated a
new copy of the class ...
 
K

Ken Kolda

As you said, every call to a web service is made on its own instance of the
WebService class. But Nicholas has recommended you use a static field, which
is shared by all instances of the web service. So, you would just create a
static instance and use lock() to ensure thread-safe access to it.

Ken
 
J

John Bailo

Thanks to both you guys, especially Nick.

Here is my code. I ran it with 3 clients calling the service in a loop
posting 1000 records each.

Before I put the .WriteLine method inside the mutex it would skip lines
or else write two numbers next to each other. Before I put the
increment of Register in the mutex it would skip or update to the same
number 2 or 3 times. With both inside the Mutex, it seems to work ok,
but I am going to load test further...

public class Service1 : System.Web.Services.WebService
{

public static int Register=5;
public static StreamWriter sw;
public static Mutex mut = new Mutex();

public Service1()
{
InitializeComponent();
}

[WebMethod]
public int Add1()
{
mut.WaitOne();
Register++;
sw.WriteLine(Register);
mut.ReleaseMutex();
return Register;
}

[WebMethod]
public void closeLog()
{
sw.Close();
}

[WebMethod]
public void openLog()
{
sw = new
StreamWriter("C:\\shareadd\\record.txt");
sw.AutoFlush=true;
}
}
 
W

Willy Denoyette [MVP]

Why don't you consider using MSMQ to let each client post it's records to a
queue,where asynchronously you can pick up them up and write them to a file
without the need to lock each client waiting for the Mutex. Sure this will
scale much better than a solution built around a global locking primitive.

Willy.


John Bailo said:
Thanks to both you guys, especially Nick.

Here is my code. I ran it with 3 clients calling the service in a loop
posting 1000 records each.

Before I put the .WriteLine method inside the mutex it would skip lines
or else write two numbers next to each other. Before I put the
increment of Register in the mutex it would skip or update to the same
number 2 or 3 times. With both inside the Mutex, it seems to work ok,
but I am going to load test further...

public class Service1 : System.Web.Services.WebService
{

public static int Register=5;
public static StreamWriter sw;
public static Mutex mut = new Mutex();

public Service1()
{
InitializeComponent();
}

[WebMethod]
public int Add1()
{
mut.WaitOne();
Register++;
sw.WriteLine(Register);
mut.ReleaseMutex();
return Register;
}

[WebMethod]
public void closeLog()
{
sw.Close();
}

[WebMethod]
public void openLog()
{
sw = new
StreamWriter("C:\\shareadd\\record.txt");
sw.AutoFlush=true;
}
}


Ken said:
As you said, every call to a web service is made on its own instance of
the
WebService class. But Nicholas has recommended you use a static field,
which
is shared by all instances of the web service. So, you would just create
a
static instance and use lock() to ensure thread-safe access to it.

Ken



Nicholas Paldino [.NET/C# MVP] wrote:

John,

You would create a static property in that case. As long as they

are in
the same app domain (and they should be), they should all hit the same
instance.



Are you saying that all clients access the same instance of a web
service -- and its associated methods ?

I thought that each call to a web service or web method instantiated a
new copy of the class ...
 
J

John Bailo

Willy Denoyette [MVP] wrote:

You know that's a good idea. In fact, I've already proposed another along
similiar lines for building a SOAP/XML Document databse web service.

In that case I would use SOAP messages, sent as email attachments rather
than via HTTP. I would set up an smtp listener and mail queue. Then I
would pull the email messages off the queue and extract the SOAP
attachment, and then finally, it to an XPath method which would retrieve or
modify the data within an XML document.

Instead of having a WSDL, I would create an email autoresponder that would
send the schema to the client as a SOAP attachment.

In this instance, I was simply trying to build a logging method for my web
service to write trace information to a log file and to capture Exceptions
thrown in my try/catch blocks.

Why don't you consider using MSMQ to let each client post it's records to
a queue,where asynchronously you can pick up them up and write them to a
file without the need to lock each client waiting for the Mutex. Sure this
will scale much better than a solution built around a global locking
primitive.

Willy.


John Bailo said:
Thanks to both you guys, especially Nick.

Here is my code. I ran it with 3 clients calling the service in a loop
posting 1000 records each.

Before I put the .WriteLine method inside the mutex it would skip lines
or else write two numbers next to each other. Before I put the
increment of Register in the mutex it would skip or update to the same
number 2 or 3 times. With both inside the Mutex, it seems to work ok,
but I am going to load test further...

public class Service1 : System.Web.Services.WebService
{

public static int Register=5;
public static StreamWriter sw;
public static Mutex mut = new Mutex();

public Service1()
{
InitializeComponent();
}

[WebMethod]
public int Add1()
{
mut.WaitOne();
Register++;
sw.WriteLine(Register);
mut.ReleaseMutex();
return Register;
}

[WebMethod]
public void closeLog()
{
sw.Close();
}

[WebMethod]
public void openLog()
{
sw = new
StreamWriter("C:\\shareadd\\record.txt");
sw.AutoFlush=true;
}
}


Ken said:
As you said, every call to a web service is made on its own instance of
the
WebService class. But Nicholas has recommended you use a static field,
which
is shared by all instances of the web service. So, you would just create
a
static instance and use lock() to ensure thread-safe access to it.

Ken




Nicholas Paldino [.NET/C# MVP] wrote:

John,

You would create a static property in that case. As long as they

are in

the same app domain (and they should be), they should all hit the same
instance.



Are you saying that all clients access the same instance of a web
service -- and its associated methods ?

I thought that each call to a web service or web method instantiated a
new copy of the class ...
 

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

Top