msvisual.com Forum Index
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

system design issue

 
Post new topic   Reply to topic    msvisual.com Forum Index -> VB Enterprise
Author Message
NickD



Joined: 04 Oct 2007
Posts: 18

PostPosted: Tue Sep 09, 2003 8:15 pm    Post subject: system design issue Reply with quote

Let's see if I can convey this easily.. the scenario I think is fairly
standard and un-complex in theory, but currently I am having to employ..
shall we say, unusual.. methods to achieve the result.

And it's working, but it may be a) a very bad design and b) missing the
obvious/good solution to the issue.

Sorry for the post length though.. and I'm using VB6 SP5 w/MSDE 2000 on a
Win2k machine (if it matters, though this may not be the target environment
anyway).

I am looking for some quick pointers please on what I should be creating to
achieve my goal, so here's the request:

Make a server (ActiveX .exe specifically) from which clients can create
objects from. The server on behalf of these clients will contain the
necessary data access code for fetching and returning stuff.

The backend where this data resides is going to be an MSDE-hosted database
for the purpose of this scenario.

The clients are just regular little VB apps that will CreateObject() from
the server (or however they should do it).

So far so good, but the specific design issue to overcome is being able to
trigger an event in the database (such as a low stock warning or something)
and to cascade this up to the "connected" clients.

I understand I can use the sp_OA* procedures from a trigger on the database
to start this ball rolling and hook into the server (ActiveX .exe) by
creating and using some sort of Alert/Warning/Trigger object within it, but
then my issue is how to know what instances of my clients are currently
running so that I can (for example) perform a RaiseEvent within the server
to pass the alerts on.

I thought about holding some sort of collection in the server that contains
references to the server objects as each client creates them, but I fear for
creating orphaned objects (when the client unloads and sets the server
object reference to nothing, the server doesn't actually unload the object
instance still being referred to by the collection until all clients have
closed -- I think?).

So what else can I do to get around this? I have one idea and made it work,
but I'm still unhappy with it.

I basically placed a form in the ActiveX .exe which will never be displayed,
whenever a client creates a server object, that server object is then
creating a new instance of this form.

When I need to alert all of the clients, in the simplest fashion I am then
just able to get my alert object raised by the sp_OA* sprocs in the
database, which iterates through the Forms collection of the server and
raises a custom event.. this event is then caught by the server object
instances that created the form, and they too raise an event up to the
actual client.

This method using forms that are inherently members of the
globally-accessible (within the project) Forms object seems to solve my
orphaned object issue, but are there other ways? This is fine this way, but
like I said I don't know if I'm missing the obvious and/or inherently
creating a very bad (kludgy) design.. I feel that I'm not necessarily
breaking any rules per se, but I am abusing them and this is why it is a
concern.

It also has issues if, for example, in the client event handler I make it
pop up a message box or whatever, since this appears to create a blocking
situation (perhaps it should just pop up a non-modal form that is
masquerading as a kind of message box?) which means other clients don't get
to be alerted until each message box in turn is closed and the event handler
returns. Not very elegant to have to require such delicate tip-toeing by
the client developer.

So anyway, this post is getting too long so I'll end it here for now; can my
concerns be addressed or have I just chosen an unusual but workable
solution? I really want to avoid such issues as circular references to
objects, or requiring clients to have to specifically call some sort of
Destroy()/Close() method on the server, or to have the alerts being raised
cause a blocking scenario (though that is the lesser evil I can manage
regardless I think).

Thanks,
Nick

P.s. x-posted to two groups (relevant ones I hope).

Archived from group: microsoft>public>vb>enterprise
Back to top
View user's profile Send private message
Pásztor, Zoltán



Joined: 04 Oct 2007
Posts: 5

PostPosted: Wed Sep 10, 2003 4:33 pm    Post subject: Re: system design issue Reply with quote

Hi Nick,

For a somewhat similar requirement I use the following approach. It isn't
perfect, but avoids callbacks, and is working rather well.

1. The monitored conditions are maintained insde the DB in a special table
by triggers that detect the changes in the status of the individual
conditions. Each item is timestamped.

2. The client components have a timer loop (activated in 5-minute intervals
in my case). The client also maintains the timestamp (dtLastReportTime) of
the last condition-change report obtained (initially set to some fictive old
value).

3. The timer event handler issues a query against the condition table,
parametrized by dtLastReportTime, to obtain the yet unseen items. If some
items are returned, then a simple message box is displayed to the user,
summarizing the new conditions. Non-modal form would cause more trouble,
because the user might be currently working with a modal form.

4. There is a separate item on the main task menu for inspecting the full
status (the content of the condition table).

5. A minor technical detail: since the resolution of the Date type in the DB
(we are working with Oracle 8.1.7) in itself is not sufficient for ensuring
unambiguous separation, in each writing transaction we force the timestamp
written to be higher than the current maximum.

hth

--
PZ


NickD wrote:
> Let's see if I can convey this easily.. the scenario I think is fairly
> standard and un-complex in theory, but currently I am having to
> employ.. shall we say, unusual.. methods to achieve the result.
>
> And it's working, but it may be a) a very bad design and b) missing
> the obvious/good solution to the issue.
>
> Sorry for the post length though.. and I'm using VB6 SP5 w/MSDE 2000
> on a Win2k machine (if it matters, though this may not be the target
> environment anyway).
>
> I am looking for some quick pointers please on what I should be
> creating to achieve my goal, so here's the request:
>
> Make a server (ActiveX .exe specifically) from which clients can
> create objects from. The server on behalf of these clients will
> contain the necessary data access code for fetching and returning
> stuff.
>
> The backend where this data resides is going to be an MSDE-hosted
> database for the purpose of this scenario.
>
> The clients are just regular little VB apps that will CreateObject()
> from the server (or however they should do it).
>
> So far so good, but the specific design issue to overcome is being
> able to trigger an event in the database (such as a low stock warning
> or something) and to cascade this up to the "connected" clients.
>
> I understand I can use the sp_OA* procedures from a trigger on the
> database to start this ball rolling and hook into the server (ActiveX
> .exe) by creating and using some sort of Alert/Warning/Trigger object
> within it, but then my issue is how to know what instances of my
> clients are currently running so that I can (for example) perform a
> RaiseEvent within the server to pass the alerts on.
>
> I thought about holding some sort of collection in the server that
> contains references to the server objects as each client creates
> them, but I fear for creating orphaned objects (when the client
> unloads and sets the server object reference to nothing, the server
> doesn't actually unload the object instance still being referred to
> by the collection until all clients have closed -- I think?).
>
> So what else can I do to get around this? I have one idea and made
> it work, but I'm still unhappy with it.
>
> I basically placed a form in the ActiveX .exe which will never be
> displayed, whenever a client creates a server object, that server
> object is then creating a new instance of this form.
>
> When I need to alert all of the clients, in the simplest fashion I am
> then just able to get my alert object raised by the sp_OA* sprocs in
> the database, which iterates through the Forms collection of the
> server and raises a custom event.. this event is then caught by the
> server object instances that created the form, and they too raise an
> event up to the actual client.
>
> This method using forms that are inherently members of the
> globally-accessible (within the project) Forms object seems to solve
> my orphaned object issue, but are there other ways? This is fine
> this way, but like I said I don't know if I'm missing the obvious
> and/or inherently creating a very bad (kludgy) design.. I feel that
> I'm not necessarily breaking any rules per se, but I am abusing them
> and this is why it is a concern.
>
> It also has issues if, for example, in the client event handler I
> make it pop up a message box or whatever, since this appears to
> create a blocking situation (perhaps it should just pop up a
> non-modal form that is masquerading as a kind of message box?) which
> means other clients don't get to be alerted until each message box in
> turn is closed and the event handler returns. Not very elegant to
> have to require such delicate tip-toeing by the client developer.
>
> So anyway, this post is getting too long so I'll end it here for now;
> can my concerns be addressed or have I just chosen an unusual but
> workable solution? I really want to avoid such issues as circular
> references to objects, or requiring clients to have to specifically
> call some sort of Destroy()/Close() method on the server, or to have
> the alerts being raised cause a blocking scenario (though that is the
> lesser evil I can manage regardless I think).
>
> Thanks,
> Nick
>
> P.s. x-posted to two groups (relevant ones I hope).
Back to top
View user's profile Send private message
NickD



Joined: 04 Oct 2007
Posts: 18

PostPosted: Wed Sep 10, 2003 5:51 pm    Post subject: Re: system design issue Reply with quote

"Pásztor, Zoltán" wrote in message@TK2MSFTNGP12.phx.gbl...
> Hi Nick,
>
> For a somewhat similar requirement I use the following approach. It isn't
> perfect, but avoids callbacks, and is working rather well.
>
> 1. The monitored conditions are maintained insde the DB in a special table
> by triggers that detect the changes in the status of the individual
> conditions. Each item is timestamped.
>
> 2. The client components have a timer loop (activated in 5-minute
intervals
> in my case). The client also maintains the timestamp (dtLastReportTime) of
> the last condition-change report obtained (initially set to some fictive
old
> value).

I neglected to mention that polling isn't viable either, it must be a
real-time response.

Whilst trying to find a better solution I stumbled on the MSDN "Coffee"
sample project and have decided to go with the interface-driven callback
solution from there.

The code I'm writing currently still doesn't appear to resolve my blocking
issue to the clients, but I feel that using the callback mechanism at least
will allow me to deal with that, the solution I had originally involving
RaiseEvents didn't look like it was going to play ball even with some
kludging.

> 3. The timer event handler issues a query against the condition table,
> parametrized by dtLastReportTime, to obtain the yet unseen items. If some
> items are returned, then a simple message box is displayed to the user,
> summarizing the new conditions. Non-modal form would cause more trouble,
> because the user might be currently working with a modal form.

This is something I'm still trying to weigh the pros and cons for. I may
just make the request that the client must make sure that it returns swiftly
and is non-blocking for now and deal with this later due to time
constraints.

> 4. There is a separate item on the main task menu for inspecting the full
> status (the content of the condition table).
>
> 5. A minor technical detail: since the resolution of the Date type in the
DB
> (we are working with Oracle 8.1.7) in itself is not sufficient for
ensuring
> unambiguous separation, in each writing transaction we force the timestamp
> written to be higher than the current maximum.
>
> hth
>
> --
> PZ
[...]

Thanks for the insight. Polling might have been viable except that in this
circumstance it was expressly forbidden; only an immediate non-polled
solution is acceptable.

Regards,
Nick
Back to top
View user's profile Send private message
Pásztor, Zoltán



Joined: 04 Oct 2007
Posts: 5

PostPosted: Wed Sep 10, 2003 7:36 pm    Post subject: Re: system design issue Reply with quote

NickD wrote:
>
> I neglected to mention that polling isn't viable either, it must be a
> real-time response.
>
> Whilst trying to find a better solution I stumbled on the MSDN
> "Coffee" sample project and have decided to go with the
> interface-driven callback solution from there.
>

What I neglected to mention is that our system is one for geographycally
distributed corporate environment.
DCOM/COM+ is not really the best choice for that, but we have had other
considerations.

If your system is confined to a single LAN, then callbacks should be fine;
otherwise there are some issues concerning firewalls. I don't have the
references at hand now, but you can find relevant discussion at the

microsoft.public.platformsdk,complus_mts

newsgroup.

Regards,

--
PZ
Back to top
View user's profile Send private message
NickD



Joined: 04 Oct 2007
Posts: 18

PostPosted: Wed Sep 10, 2003 8:37 pm    Post subject: Re: system design issue Reply with quote

"Pásztor, Zoltán" wrote in message@TK2MSFTNGP09.phx.gbl...
[...]
> What I neglected to mention is that our system is one for geographycally
> distributed corporate environment.
> DCOM/COM+ is not really the best choice for that, but we have had other
> considerations.
>
> If your system is confined to a single LAN, then callbacks should be fine;
> otherwise there are some issues concerning firewalls. I don't have the
> references at hand now, but you can find relevant discussion at the
>
> microsoft.public.platformsdk,complus_mts
>
> newsgroup.
>
> Regards,
>
> --
> PZ

I can appreciate the reasons for that Smile In my situation the scope is only
LAN with no firewalls to contend with.

So far things are good, however I do have a problem that I can't quite
figure out..

The problem domain is this; I have clients connecting to an ActiveX .exe,
they're sharing the use of an object (public not creatable, global instance
in the .exe server and passing references to this to the clients). I can
confirm that 3 clients and 1 server are all running and talking, no other
instances.

I then need to trigger an alert from the database (MSDE), so I also have
created an Alert class and I am invoking this through the sp_OACreate, etc.,
system sprocs in SQL. The Alert object created then tries to become another
client to the .exe server but it isn't working.

What seems to be happening is that it's creating another instance of the
server with no other clients attached.

I have tried placing this Alert class inside the .exe server as well as in
its own ActiveX .dll or .exe, and the behaviour is always the same.. it
makes a new server instance, realises it is the only client, and can't
proceed.

However.. let's say I have this ActiveX .dll with the Alert class inside, if
I then run that in the VB IDE (with "Wait for components to be created"
selected) and then fire the sprocs from MSDE it connects to the shared
instance of the server fine and becomes client number 4.

How can I get it to do the same thing from the compiled version of the
class? Am I missing something simple?

I have tried (in this Alert class, contained in a .exe/.dll by itself) both
GetObject() to try and detect the running server as well CreateObject() on
my server's "connector" class that returns an instance to the shared object
without success.

Thanks again for your advice, this is a new area for me to work in. Oh, and
if it matters I'm not using COM+ to my knowledge.. not even DCOM really in
the test scenarios (everything is just running on the one box with plain
ActiveX and OLE Automation), though it will be deployed to use DCOM once it
is functional.

Regards,
Nick
Back to top
View user's profile Send private message
Helene Day



Joined: 04 Oct 2007
Posts: 2

PostPosted: Wed Sep 10, 2003 4:00 pm    Post subject: Re: system design issue Reply with quote

I had the same problem long time ago. I had to change the DCOM setting
(dcomcnfg.exe) of my Active X.

I had to change the security option (access and launch permissions) and the
Identity settings, such as run as a specific user....

Sorry I don't recall the exact settings. I had two problems to resolve, the
creation of one singleton, and then I had to resolve a problem when the
Active X was raising events.

Helene


"NickD" wrote in message@TK2MSFTNGP12.phx.gbl...
> "Pásztor, Zoltán" wrote in message
> @TK2MSFTNGP09.phx.gbl...
> [...]
> > What I neglected to mention is that our system is one for geographycally
> > distributed corporate environment.
> > DCOM/COM+ is not really the best choice for that, but we have had other
> > considerations.
> >
> > If your system is confined to a single LAN, then callbacks should be
fine;
> > otherwise there are some issues concerning firewalls. I don't have the
> > references at hand now, but you can find relevant discussion at the
> >
> > microsoft.public.platformsdk,complus_mts
> >
> > newsgroup.
> >
> > Regards,
> >
> > --
> > PZ
>
> I can appreciate the reasons for that Smile In my situation the scope is
only
> LAN with no firewalls to contend with.
>
> So far things are good, however I do have a problem that I can't quite
> figure out..
>
> The problem domain is this; I have clients connecting to an ActiveX .exe,
> they're sharing the use of an object (public not creatable, global
instance
> in the .exe server and passing references to this to the clients). I can
> confirm that 3 clients and 1 server are all running and talking, no other
> instances.
>
> I then need to trigger an alert from the database (MSDE), so I also have
> created an Alert class and I am invoking this through the sp_OACreate,
etc.,
> system sprocs in SQL. The Alert object created then tries to become
another
> client to the .exe server but it isn't working.
>
> What seems to be happening is that it's creating another instance of the
> server with no other clients attached.
>
> I have tried placing this Alert class inside the .exe server as well as in
> its own ActiveX .dll or .exe, and the behaviour is always the same.. it
> makes a new server instance, realises it is the only client, and can't
> proceed.
>
> However.. let's say I have this ActiveX .dll with the Alert class inside,
if
> I then run that in the VB IDE (with "Wait for components to be created"
> selected) and then fire the sprocs from MSDE it connects to the shared
> instance of the server fine and becomes client number 4.
>
> How can I get it to do the same thing from the compiled version of the
> class? Am I missing something simple?
>
> I have tried (in this Alert class, contained in a .exe/.dll by itself)
both
> GetObject() to try and detect the running server as well CreateObject() on
> my server's "connector" class that returns an instance to the shared
object
> without success.
>
> Thanks again for your advice, this is a new area for me to work in. Oh,
and
> if it matters I'm not using COM+ to my knowledge.. not even DCOM really in
> the test scenarios (everything is just running on the one box with plain
> ActiveX and OLE Automation), though it will be deployed to use DCOM once
it
> is functional.
>
> Regards,
> Nick
>
>
Back to top
View user's profile Send private message
Helene Day



Joined: 04 Oct 2007
Posts: 2

PostPosted: Wed Sep 10, 2003 4:16 pm    Post subject: Re: system design issue Reply with quote

OK, I found the explaination in my lab book:

Came from MS since I had called them for help:

Problem Statement: You have a DCOM server (Active X exe) which lets multiple
clients share access to global data. By default, clients running under
different identities will each launch a separate instance of the DCOM server
process, so they do not shate global data. If you solve this problem by
running the DCOM server under a fixed identity (via dcomcnfg.exe identify
tab), then you get error 70 "permission denied" when creating the object our
of the DCOM serber- but this only happens if you use withevents.

Cause: The withevents keyword causes the server process to call back into
the client process. Just as the clients needed appropriate DCOM
launch/access permissions to call into the server, now the server's indetity
needs DCOM access permission to calll back into the client.

Resolution:
Adding the server's identity to the default DCOM access permissions allows
the server to call back into the client. Note you must use the default DCOM
permissions since there is no entry in DCOM for the client. However, for the
permissions that control what client cal call "into" the server process, you
cam use the custom DCOM permissions for you application....

I hope this information can help you.

Helene

"NickD" wrote in message@TK2MSFTNGP12.phx.gbl...
> "Pásztor, Zoltán" wrote in message
> @TK2MSFTNGP09.phx.gbl...
> [...]
> > What I neglected to mention is that our system is one for geographycally
> > distributed corporate environment.
> > DCOM/COM+ is not really the best choice for that, but we have had other
> > considerations.
> >
> > If your system is confined to a single LAN, then callbacks should be
fine;
> > otherwise there are some issues concerning firewalls. I don't have the
> > references at hand now, but you can find relevant discussion at the
> >
> > microsoft.public.platformsdk,complus_mts
> >
> > newsgroup.
> >
> > Regards,
> >
> > --
> > PZ
>
> I can appreciate the reasons for that Smile In my situation the scope is
only
> LAN with no firewalls to contend with.
>
> So far things are good, however I do have a problem that I can't quite
> figure out..
>
> The problem domain is this; I have clients connecting to an ActiveX .exe,
> they're sharing the use of an object (public not creatable, global
instance
> in the .exe server and passing references to this to the clients). I can
> confirm that 3 clients and 1 server are all running and talking, no other
> instances.
>
> I then need to trigger an alert from the database (MSDE), so I also have
> created an Alert class and I am invoking this through the sp_OACreate,
etc.,
> system sprocs in SQL. The Alert object created then tries to become
another
> client to the .exe server but it isn't working.
>
> What seems to be happening is that it's creating another instance of the
> server with no other clients attached.
>
> I have tried placing this Alert class inside the .exe server as well as in
> its own ActiveX .dll or .exe, and the behaviour is always the same.. it
> makes a new server instance, realises it is the only client, and can't
> proceed.
>
> However.. let's say I have this ActiveX .dll with the Alert class inside,
if
> I then run that in the VB IDE (with "Wait for components to be created"
> selected) and then fire the sprocs from MSDE it connects to the shared
> instance of the server fine and becomes client number 4.
>
> How can I get it to do the same thing from the compiled version of the
> class? Am I missing something simple?
>
> I have tried (in this Alert class, contained in a .exe/.dll by itself)
both
> GetObject() to try and detect the running server as well CreateObject() on
> my server's "connector" class that returns an instance to the shared
object
> without success.
>
> Thanks again for your advice, this is a new area for me to work in. Oh,
and
> if it matters I'm not using COM+ to my knowledge.. not even DCOM really in
> the test scenarios (everything is just running on the one box with plain
> ActiveX and OLE Automation), though it will be deployed to use DCOM once
it
> is functional.
>
> Regards,
> Nick
>
>
Back to top
View user's profile Send private message
NickD



Joined: 04 Oct 2007
Posts: 18

PostPosted: Thu Sep 11, 2003 7:12 pm    Post subject: Re: system design issue Reply with quote

"Helene Day" wrote in message@TK2MSFTNGP11.phx.gbl...
> I had the same problem long time ago. I had to change the DCOM setting
> (dcomcnfg.exe) of my Active X.
>
> I had to change the security option (access and launch permissions) and
the
> Identity settings, such as run as a specific user....
>
> Sorry I don't recall the exact settings. I had two problems to resolve,
the
> creation of one singleton, and then I had to resolve a problem when the
> Active X was raising events.
>
> Helene
[...]

Thanks again, I got it working now with your help and another post I googled
as part of the solution was to also change the SQL Server service* to log on
as the same user as the ActiveX .exe (and since only services can be set to
run with the local System account, the change had to be made to SQL rather
than vice versa).

I didn't even realise I was already in a DCOM config situation at this stage
of the development, I was hoping that running everything whilst I was logged
in as myself on a single machine would mean I could tackle that later, but
now I've learnt otherwise.

Regards,
Nick

* Because I'm using automation services from within via system sprocs
(sp_OA*).

Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    msvisual.com Forum Index -> VB Enterprise All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group