1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
// **********************************************************************
//
// Copyright (c) 2001
// MutableRealms, Inc.
// Huntsville, AL, USA
//
// All Rights Reserved
//
// **********************************************************************
#include <Ice/Ice.h>
#include <IcePack/Forward.h>
#include <IcePack/Admin.h>
#include <sstream>
using namespace std;
using namespace Ice;
using namespace IcePack;
IcePack::Forward::Forward(const CommunicatorPtr& communicator, const AdminPtr& admin) :
_communicator(communicator),
_admin(admin)
{
#ifndef WIN32
_activator = new Activator(_communicator);
_activator->start();
PropertiesPtr properties = communicator->getProperties();
string value;
value = properties->getProperty("IcePack.Activator.WaitTime");
if (value.length())
{
_waitTime = atoi(value.c_str());
if (_waitTime < 0)
{
_waitTime = 0;
}
}
else
{
_waitTime = 10;
}
#endif
}
IcePack::Forward::~Forward()
{
#ifndef WIN32
_activator->destroy();
#endif
}
ObjectPtr
IcePack::Forward::locate(const ObjectAdapterPtr& adapter, const string& identity, ObjectPtr&)
{
//
// Look up the server description
//
ServerDescription desc = _admin->find(identity);
//
// If we didn't find a server description, we return null, meaning
// that the client will get an "object not exist" exception.
//
if (!desc.object)
{
return 0;
}
#ifndef WIN32
//
// We only try to activate if we have a path for the server
//
if (!desc.path.empty())
{
try
{
bool doSleep = false;
int count = 0;
while (true)
{
try
{
//
// Activate the server. If the server is already
// running, this operation does nothing.
//
if (_activator->activate(desc))
{
//
// If we just activated the server, we sleep
// below, to give the server some time to
// start up.
//
doSleep = true;
}
if (doSleep)
{
sleep(1);
}
//
// Try to ping the server, to make sure that it is
// really running. Note that even if activate()
// above returns false, i.e., if activate()
// indicates that the server was already running,
// it's still possible that the server shut down
// in the meantime, for example, because of a
// server timeout, a crash, or an explicit
// shutdown method.
//
desc.object->_ping();
//
// Everything ok, the server is now up and
// running. The ping above also has the effect
// that the server idle timeout (if set) has been
// reset. If we wouldn't ping, there would be a
// higher chance that the server shuts down
// because of an idle timeout while we send back
// the location forward to the client.
//
break;
}
catch(const SocketException&)
{
//
// Ooops, we got a socket exception while trying
// to ping the server. Let's set the doSleep flag
// to give the server more time before we try
// again.
//
if (++count >= _waitTime)
{
throw;
}
doSleep = true;
}
}
}
catch(const LocalException& ex)
{
//
// If we get an exception, all we an do is to log it and
// to send a location forward to the client, which will
// then get a similar exception.
//
ostringstream s;
s << "exception during server activation:\n" << ex;
_communicator->getLogger()->error(s.str());
}
}
#endif
throw LocationForward(desc.object);
}
void
IcePack::Forward::finished(const ObjectAdapterPtr&, const string&, const ObjectPtr&, const ObjectPtr&)
{
// Nothing to do
}
|