~ubuntu-branches/ubuntu/breezy/ncbi-tools6/breezy

« back to all changes in this revision

Viewing changes to connect/lbapi/lbapi.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2002-04-04 22:13:09 UTC
  • Revision ID: james.westby@ubuntu.com-20020404221309-vfze028rfnlrldct
Tags: upstream-6.1.20011220a
ImportĀ upstreamĀ versionĀ 6.1.20011220a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: lbapi.c,v 1.11 1999/02/26 21:17:36 shavirin Exp $
 
2
* ===========================================================================
 
3
*
 
4
*                            PUBLIC DOMAIN NOTICE
 
5
*               National Center for Biotechnology Information
 
6
*
 
7
*  This software/database is a "United States Government Work" under the
 
8
*  terms of the United States Copyright Act.  It was written as part of
 
9
*  the author's official duties as a United States Government employee and
 
10
*  thus cannot be copyrighted.  This software/database is freely available
 
11
*  to the public for use. The National Library of Medicine and the U.S.
 
12
*  Government have not placed any restriction on its use or reproduction.
 
13
*
 
14
*  Although all reasonable efforts have been taken to ensure the accuracy
 
15
*  and reliability of the software and data, the NLM and the U.S.
 
16
*  Government do not and cannot warrant the performance or results that
 
17
*  may be obtained by using this software or data. The NLM and the U.S.
 
18
*  Government disclaim all warranties, express or implied, including
 
19
*  warranties of performance, merchantability or fitness for any particular
 
20
*  purpose.
 
21
*
 
22
*  Please cite the author in any work or product based on this material.
 
23
*
 
24
* ===========================================================================
 
25
*
 
26
* File Name:  $RCSfile: lbapi.c,v $
 
27
*
 
28
* Author:  Sergei Shavirin
 
29
*
 
30
* Initial Version Creation Date: 03/24/1997
 
31
*
 
32
* $Revision: 1.11 $
 
33
*
 
34
* File Description:
 
35
*        Utilities for the load balancing client library
 
36
*
 
37
* $Log: lbapi.c,v $
 
38
* Revision 1.11  1999/02/26 21:17:36  shavirin
 
39
* Moved al ntohl function to the lbdaemon area.
 
40
*
 
41
* Revision 1.10  1999/02/02 21:10:28  shavirin
 
42
* Changed formula to calculate status:
 
43
* Added adjustment of load and used 4th lb-parameter.
 
44
*
 
45
* Revision 1.9  1998/12/07 19:01:50  shavirin
 
46
* Added complience with little-big endian platforms.
 
47
*
 
48
* Revision 1.8  1998/09/22 17:22:57  yaschenk
 
49
* LBCalculateStatus: changed additive constant 1 which is very high to 0.01
 
50
*
 
51
* Revision 1.7  1998/05/08 15:26:57  vakatov
 
52
* [LB_DIRECT]  now can skip IP addresses(for the dispatcher hosts) which
 
53
* were already offered by the load-balancing daemon but failed by some reason
 
54
*
 
55
* Revision 1.6  1998/04/23 14:26:18  shavirin
 
56
* Added include #include <sys/ipc.h>
 
57
*
 
58
* Revision 1.5  1998/04/07 14:17:27  vakatov
 
59
* Skip all code(#ifdef'd) if LB_DIRECT is not defined or if compiled on
 
60
* any platform but Solaris and IRIX
 
61
*
 
62
* Revision 1.4  1998/04/03 21:50:08  shavirin
 
63
* Added include file for TCP/IP address define
 
64
*
 
65
* Revision 1.3  1998/04/03 21:16:47  vakatov
 
66
* Cleaned up the code and prepared "lbapi.[ch]" to be moved to "netcli" lib
 
67
*
 
68
* Revision 1.2  1998/04/02 17:36:04  yaschenk
 
69
* Adding dispd-ncbid shortcut when they are on the same server, adding preference to same server in stateless mode
 
70
*
 
71
* Revision 1.1  1998/03/06 18:54:25  shavirin
 
72
* Initial revision
 
73
* ==========================================================================
 
74
*/
 
75
 
 
76
#include <lbapi.h>
 
77
 
 
78
#ifdef LB_DIRECT
 
79
 
 
80
#include <stdio.h>
 
81
#include <stdlib.h>
 
82
#include <string.h>
 
83
#include <time.h>
 
84
#include <netinet/in.h>
 
85
#include <arpa/inet.h>
 
86
#include <netdb.h>
 
87
#include <sys/socket.h>
 
88
#include <sys/ipc.h>
 
89
#include <sys/shm.h>
 
90
 
 
91
#define SHM_FLAGS ((SHM_R >> 6) | (SHM_R >> 3) | SHM_R)
 
92
#define MAX_RAND_NUMBER 0x7FFF 
 
93
 
 
94
 
 
95
typedef struct LBUserInfo {
 
96
  LB_MessagePtr lbtable;
 
97
  int shmemid;
 
98
} LBUserInfo, *LBUserInfoPtr;
 
99
 
 
100
typedef struct LBStatus {
 
101
  int   index;
 
102
  float status;
 
103
  int   skip;
 
104
} LBStatus, *LBStatusPtr;
 
105
 
 
106
 
 
107
static LBUserInfo theinfo;
 
108
 
 
109
static float LBCalculateStatus(LB_MessagePtr msgp)
 
110
{
 
111
    float status;
 
112
    int cpuload;
 
113
 
 
114
    /* Penalize machine if load[0]/256 > load[1] */
 
115
 
 
116
    cpuload = msgp->load[0];
 
117
 
 
118
    if(msgp->load[0] > (msgp->load[1]<<8))
 
119
        cpuload *= exp(msgp->load[0] / (256.0*msgp->load[1]) - 1.0);
 
120
    
 
121
    status = 0.01 + 256000*msgp->load[1] / (float)(cpuload*msgp->load[2] + 1);
 
122
    
 
123
    status = status * msgp->load[3];
 
124
    
 
125
    return status;
 
126
}
 
127
 
 
128
static int LBClientInit(void)
 
129
{
 
130
  /* setting it completely random */
 
131
  srand(time(NULL));
 
132
 
 
133
  if ((theinfo.shmemid = shmget(LB_SHARED_KEY, 
 
134
                                sizeof(LB_Message) * MAX_NUM_HOSTS, 
 
135
                                SHM_FLAGS)) < 0)
 
136
    return -1;
 
137
    
 
138
  if ((theinfo.lbtable = (LB_MessagePtr)
 
139
      shmat(theinfo.shmemid, (void *)0, SHM_RDONLY)) == (LB_MessagePtr)-1)
 
140
    return -1;
 
141
    
 
142
  return 0;
 
143
}
 
144
 
 
145
 
 
146
extern int LBPrintTable(void)
 
147
{
 
148
    int i, j;
 
149
    struct sockaddr_in sin;
 
150
    struct hostent    *hp;
 
151
    float status;
 
152
    LB_MessagePtr lbtable;
 
153
    
 
154
    if((lbtable = theinfo.lbtable) == NULL) {
 
155
        if(LBClientInit() < 0)
 
156
            return -1;
 
157
        lbtable = theinfo.lbtable;
 
158
    }
 
159
    
 
160
  for(j = 0; j < MAX_NUM_HOSTS; j++) {
 
161
      if(lbtable[j].address != 0) {
 
162
          sin.sin_addr.s_addr = lbtable[j].address;
 
163
                    
 
164
          hp = gethostbyaddr((char *)&sin.sin_addr, 
 
165
                             sizeof (sin.sin_addr), AF_INET);
 
166
          printf("%-15s: ", 
 
167
                 hp == NULL? inet_ntoa(sin.sin_addr) : hp->h_name);
 
168
          
 
169
          status = LBCalculateStatus(&lbtable[j]);
 
170
          printf("%-10.2f ", status);
 
171
          
 
172
          for(i = 0; i < NUM_LOAD_PARAMETERS; i++)
 
173
              printf("%5d ", lbtable[j].load[i]);
 
174
          
 
175
          for(i = 0; i < MAX_NUM_SERVICES; i++) {
 
176
              if(*lbtable[j].service[i] != '\0')
 
177
                  printf("%s ", lbtable[j].service[i]);
 
178
          }
 
179
          printf("\n");
 
180
          fflush(stdout);
 
181
      }
 
182
  }
 
183
  printf("----\n");
 
184
  
 
185
  return 0;
 
186
}
 
187
 
 
188
 
 
189
extern unsigned LBGetIPAddress(const char *service, unsigned int pref_ip,
 
190
                               unsigned *skip_ip, size_t n_skip)
 
191
{
 
192
  int i, j, k;
 
193
  LBStatus trace[MAX_NUM_HOSTS];
 
194
  int count;
 
195
  float status, all_status, point;
 
196
  LB_MessagePtr lbtable;
 
197
 
 
198
  if (!theinfo.lbtable  &&  LBClientInit() < 0)
 
199
    return 0;
 
200
 
 
201
  lbtable = theinfo.lbtable;
 
202
 
 
203
  memset(trace, '\0', sizeof(trace));
 
204
 
 
205
  /* the hosts to be skipped */
 
206
  for (j = 0;  j < MAX_NUM_HOSTS;  j++) {
 
207
    size_t m;
 
208
    for (m = 0;  m < n_skip;  m++)
 
209
      if (lbtable[j].address == skip_ip[m]) {
 
210
        trace[j].skip = 1;
 
211
        break;
 
212
      }
 
213
  }
 
214
 
 
215
  /* first try to find the preferred address */
 
216
  if ( pref_ip ) {
 
217
    for (j = 0, i = 0;  j < MAX_NUM_HOSTS;  j++) {
 
218
      if (pref_ip == lbtable[j].address) {
 
219
        if ( trace[j].skip )
 
220
          break;
 
221
        for (k = 0;  k < MAX_NUM_SERVICES;  k++) {
 
222
          if ( !strcmp(lbtable[j].service[k], service) )
 
223
            return pref_ip;
 
224
        }
 
225
        break;
 
226
      }
 
227
    }
 
228
  }
 
229
    
 
230
  all_status = 0;
 
231
  for (j = 0, i = 0;  j < MAX_NUM_HOSTS;  j++) {
 
232
    if ( trace[j].skip )
 
233
      continue;
 
234
 
 
235
    for (k = 0;  k < MAX_NUM_SERVICES;  k++) {
 
236
      if(!strcmp(lbtable[j].service[k], service)) {
 
237
        status = LBCalculateStatus(&lbtable[j]);
 
238
        all_status += status;
 
239
        trace[i].status = all_status;
 
240
        trace[i].index = j;
 
241
        i++;
 
242
        break;
 
243
      }
 
244
    }
 
245
  }
 
246
  if ( !i )
 
247
    return 0;
 
248
 
 
249
  count = i;
 
250
  point = (float)(trace[count-1].status * rand()) / (float)MAX_RAND_NUMBER;
 
251
    
 
252
  for (i = 0;  i < count;  i++) {
 
253
    if (point < trace[i].status)
 
254
      break;
 
255
  }
 
256
 
 
257
  return lbtable[trace[i].index].address;
 
258
}
 
259
 
 
260
#endif /* LB_DIRECT */