cvs commit: jakarta-tomcat-connectors/ajp/proxy proxy_balancer.c

2004-08-10 Thread mturk
mturk   2004/08/10 06:52:51

  Modified:ajp/proxy proxy_balancer.c
  Log:
  Use the proxy_runtime_stat that either comes from scoreboard or
  directly allocating memory if there is no scoreboard support or it is not
  neaded, due to the fact that we have single child process.
  
  Revision  ChangesPath
  1.5   +9 -8  jakarta-tomcat-connectors/ajp/proxy/proxy_balancer.c
  
  Index: proxy_balancer.c
  ===
  RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/proxy_balancer.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- proxy_balancer.c  9 Aug 2004 15:08:28 -   1.4
  +++ proxy_balancer.c  10 Aug 2004 13:52:51 -  1.5
  @@ -31,6 +31,7 @@
   #define PROXY_BALANCER_UNLOCK(b)APR_SUCCESS
   #endif
   
  +
   /* Retrieve the parameter with the given name*/
   static char *get_path_param(apr_pool_t *pool, char *url,
   const char *name)
  @@ -162,7 +163,7 @@
* This is for cases when worker is in error state.
* It will force the even request distribution
*/
  -total_factor += worker-lbfactor;
  +total_factor += worker-s-lbfactor;
   }
   worker++;
   }
  @@ -207,7 +208,7 @@
* Lbstatus is of higher importance then
* the number of empty slots.
*/
  -if (worker-lbstatus  candidate-lbstatus) {
  +if (worker-s-lbstatus  candidate-s-lbstatus) {
   candidate = worker;
   }
   }
  @@ -221,9 +222,9 @@
   /* XXX: The lbfactor can be update using bytes transfered
* Right now, use the round-robin scheme
*/
  -worker-lbstatus += worker-lbfactor;
  -if (worker-lbstatus = total_factor)
  -worker-lbstatus = worker-lbfactor;
  +worker-s-lbstatus += worker-s-lbfactor;
  +if (worker-s-lbstatus = total_factor)
  +worker-s-lbstatus = worker-s-lbfactor;
   }
   worker++;
   }
  @@ -289,9 +290,9 @@
   workers = (proxy_runtime_worker *)(*balancer)-workers-elts;
   for (i = 0; i  (*balancer)-workers-nelts; i++) {
   /* For now assume that all workers are OK */
  -workers-lbstatus += workers-lbfactor;
  -if (workers-lbstatus = 100.0)
  -workers-lbstatus = workers-lbfactor;
  +workers-s-lbstatus += workers-s-lbfactor;
  +if (workers-s-lbstatus = 100.0)
  +workers-s-lbstatus = workers-s-lbfactor;
   workers++;
   }
   }
  
  
  

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



cvs commit: jakarta-tomcat-connectors/ajp/proxy proxy_balancer.c

2004-08-10 Thread mturk
mturk   2004/08/10 11:02:54

  Modified:ajp/proxy proxy_balancer.c
  Log:
  Fix the url rewriting, and few minor developement bugs.
  
  Revision  ChangesPath
  1.7   +22 -10jakarta-tomcat-connectors/ajp/proxy/proxy_balancer.c
  
  Index: proxy_balancer.c
  ===
  RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/proxy_balancer.c,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- proxy_balancer.c  10 Aug 2004 14:58:24 -  1.6
  +++ proxy_balancer.c  10 Aug 2004 18:02:54 -  1.7
  @@ -150,7 +150,7 @@
* for the workers flagged as IN_ERROR
*/
   if (!PROXY_WORKER_IS_USABLE(worker-w))
  -ap_proxy_retry_worker(BALANCER, worker-w, r-server)
  +ap_proxy_retry_worker(BALANCER, worker-w, r-server);
   /* If the worker is not in error state
* or not disabled.
*/
  @@ -202,6 +202,7 @@
* error state or disabled.
* Now calculate the appropriate one 
*/
  +worker = (proxy_runtime_worker *)balancer-workers-elts;
   for (i = 0; i  balancer-workers-nelts; i++) {
   /* If the worker is not error state
* or not in disabled mode
  @@ -217,6 +218,7 @@
   }
   worker++;
   }
  +worker = (proxy_runtime_worker *)balancer-workers-elts;
   for (i = 0; i  balancer-workers-nelts; i++) {
   /* If the worker is not error state
* or not in disabled mode
  @@ -238,8 +240,12 @@
   static int rewrite_url(request_rec *r, proxy_worker *worker,
   char **url)
   {
  -const char *path = strchr(*url, '/');
  +const char *scheme = strstr(*url, ://);
  +const char *path = NULL;
   
  +if (scheme)
  +path = strchr(scheme + 3, '/');
  +
   /* we break the URL into host, port, uri */
   if (!worker) {
   return ap_proxyerror(r, HTTP_BAD_REQUEST, apr_pstrcat(r-pool,
  @@ -248,9 +254,6 @@
   }
   
   *url = apr_pstrcat(r-pool, worker-name, path, NULL);
  -
  -ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r-server,
  - proxy: BALANCER rewriting to %s, *url);
  
   return OK;
   }
  @@ -276,7 +279,7 @@
   if (!runtime) {
   if (route  (*balancer)-sticky_force) {
   ap_log_error(APLOG_MARK, APLOG_ERR, 0, r-server,
  - balancer: (%s). All workers in error state for route 
(%s),
  + proxy: BALANCER: (%s). All workers are in error state for 
route (%s),
(*balancer)-name, route);
   return HTTP_SERVICE_UNAVAILABLE;
   }
  @@ -304,14 +307,14 @@
*/
   if ((rv = PROXY_BALANCER_LOCK(*balancer)) != APR_SUCCESS) {
   ap_log_error(APLOG_MARK, APLOG_ERR, rv, r-server,
  - proxy_balancer_pre_request: lock);
  + proxy: BALANCER: lock);
   return DECLINED;
   }
   if (!*worker) {
   runtime = find_best_worker(*balancer, r);
   if (!runtime) {
   ap_log_error(APLOG_MARK, APLOG_ERR, 0, r-server,
  - balancer: (%s). All workers in error state.,
  + proxy: BALANCER: (%s). All workers are in error state,
(*balancer)-name);
   
   PROXY_BALANCER_UNLOCK(*balancer);
  @@ -326,6 +329,13 @@
   PROXY_BALANCER_UNLOCK(*balancer);
   
   access_status = rewrite_url(r, *worker, url);
  +ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r-server,
  + proxy_balancer_pre_request rewriting to %s, *url);
  +ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r-server,
  + proxy_balancer_pre_request worker (%s) free %d,
  + (*worker)-name,
  + (*worker)-cp-nfree);
  +
   return access_status;
   } 
   
  @@ -341,8 +351,8 @@
   apr_status_t rv;
   if ((rv = PROXY_BALANCER_LOCK(balancer)) != APR_SUCCESS) {
   ap_log_error(APLOG_MARK, APLOG_ERR, rv, r-server,
  - proxy_balancer_post_request: lock);
  -return DECLINED;
  + proxy: BALANCER: lock);
  +return HTTP_INTERNAL_SERVER_ERROR;
   }
   /* increase the free channels number */
   if (worker-cp-nfree)
  @@ -354,6 +364,8 @@
   PROXY_BALANCER_UNLOCK(balancer);
   access_status = OK;
   }
  +ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r-server,
  + proxy_balancer_post_request for (%s), balancer-name);
   
   return access_status;
   } 
  
  
  

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



cvs commit: jakarta-tomcat-connectors/ajp/proxy proxy_balancer.c

2004-08-09 Thread mturk
mturk   2004/08/09 01:06:40

  Added:   ajp/proxy proxy_balancer.c
  Log:
  Add proxy_balancer initial code.
  
  Revision  ChangesPath
  1.1  jakarta-tomcat-connectors/ajp/proxy/proxy_balancer.c
  
  Index: proxy_balancer.c
  ===
  /* Copyright 1999-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the License);
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an AS IS BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  /* Load balancer module for Apache proxy */
  
  #define CORE_PRIVATE
  
  #include mod_proxy.h
  #include ap_mpm.h
  #include apr_version.h
  
  module AP_MODULE_DECLARE_DATA proxy_balancer_module;
  
  #if APR_HAS_THREADS1
  #define PROXY_BALANCER_LOCK(b)  apr_thread_mutex_lock((b)-mutex)
  #define PROXY_BALANCER_UNLOCK(b)apr_thread_mutex_unlock((b)-mutex)
  #else
  #define PROXY_BALANCER_LOCK(b)  APR_SUCCESS
  #define PROXY_BALANCER_UNLOCK(b)APR_SUCCESS
  #endif
  
  /* Retrieve the parameter with the given name*/
  static char *get_path_param(apr_pool_t *pool, char *url,
  const char *name)
  {
  char *path = NULL;
  
  for (path = strstr(url, name); path; path = strstr(path + 1, name)) {
  path += (strlen(name) + 1);
  if (*path == '=') {
  /*
   * Session path was found, get it's value
   */
  ++path;
  if (strlen(path)) {
  char *q;
  path = apr_pstrdup(pool, path);
  if ((q = strchr(path, '?')))
  *q = '\0';
  return path;
  }
  }
  }
  return NULL;
  }
  
  static char *get_cookie_param(request_rec *r, const char *name)
  {
  const char *cookies;
  const char *start_cookie;
  
  if ((cookies = apr_table_get(r-headers_in, Cookie))) {
  for (start_cookie = strstr(cookies, name); start_cookie; 
   start_cookie = strstr(start_cookie + 1, name)) {
  if (start_cookie == cookies ||
  start_cookie[-1] == ';' ||
  start_cookie[-1] == ',' ||
  isspace(start_cookie[-1])) {
  
  start_cookie += strlen(name);
  while(*start_cookie  isspace(*start_cookie))
  ++start_cookie;
  if (*start_cookie == '='  start_cookie[1]) {
  /*
   * Session cookie was found, get it's value
   */
  char *end_cookie, *cookie;
  ++start_cookie;
  cookie = apr_pstrdup(r-pool, start_cookie);
  if ((end_cookie = strchr(cookie, ';')) != NULL)
  *end_cookie = '\0';
  if((end_cookie = strchr(cookie, ',')) != NULL)
  *end_cookie = '\0';
  return cookie;
  }
  }
  } 
  }
  return NULL;
  }
  
  static proxy_runtime_worker *find_route_worker(proxy_balancer *balancer,
 const char *route)
  {
  int i;
  proxy_runtime_worker *worker = (proxy_runtime_worker *)balancer-workers-elts;
  for (i = 0; i  balancer-workers-nelts; i++) {
  if (worker-route  strcmp(worker-route, route) == 0) {
  return worker;
  }
  worker++;
  }
  return NULL;
  }
  
  static proxy_runtime_worker *find_session_route(proxy_balancer *balancer,
  request_rec *r,
  char **route,
  char **url)
  {
  if (!balancer-sticky)
  return NULL;
  /* Try to find the sticky route inside url */
  *route = get_path_param(r-pool, *url, balancer-sticky);
  if (!*route)
  *route = get_cookie_param(r, balancer-sticky);
  if (*route) {
  proxy_runtime_worker *worker =  find_route_worker(balancer, *route);
  /* TODO: make worker status codes */
  /* See if we have a redirection route */
  if (worker  worker-w-status  2  worker-redirect)
  worker = find_route_worker(balancer, worker-redirect);
  else
  worker = NULL;
  return worker;
  }
  else
  return NULL;
  }
  
  

cvs commit: jakarta-tomcat-connectors/ajp/proxy proxy_balancer.c

2004-08-09 Thread mturk
mturk   2004/08/09 02:55:47

  Modified:ajp/proxy proxy_balancer.c
  Log:
  Add finding of a most suitable worker.
  The implemeted algo is round-robin with boost factor.
  
  Revision  ChangesPath
  1.2   +120 -2jakarta-tomcat-connectors/ajp/proxy/proxy_balancer.c
  
  Index: proxy_balancer.c
  ===
  RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/proxy_balancer.c,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- proxy_balancer.c  9 Aug 2004 08:06:40 -   1.1
  +++ proxy_balancer.c  9 Aug 2004 09:55:47 -   1.2
  @@ -23,7 +23,7 @@
   
   module AP_MODULE_DECLARE_DATA proxy_balancer_module;
   
  -#if APR_HAS_THREADS1
  +#if APR_HAS_THREADS
   #define PROXY_BALANCER_LOCK(b)  apr_thread_mutex_lock((b)-mutex)
   #define PROXY_BALANCER_UNLOCK(b)apr_thread_mutex_unlock((b)-mutex)
   #else
  @@ -130,6 +130,90 @@
   return NULL;
   }
   
  +static proxy_runtime_worker *find_best_worker(proxy_balancer *balancer,
  +  request_rec *r)
  +{
  +int i;
  +double total_status = 0.0;
  +proxy_runtime_worker *worker = (proxy_runtime_worker *)balancer-workers-elts;
  +proxy_runtime_worker *candidate = NULL;
  +
  +/* First try to see if we have available candidate */
  +for (i = 0; i  balancer-workers-nelts; i++) {
  +/* If the worker is not error state
  + * or not in disabled mode
  + */
  +
  +/* TODO: read the scoreboard status */
  +if (worker-w-status  2) {
  +if (!candidate)
  +candidate = worker;
  +else {
  +/* See if the worker has a larger number of free channels */
  +if (worker-w-cp-nfree  candidate-w-cp-nfree)
  +candidate = worker;
  +}
  +total_status += worker-lbstatus;
  +}
  +worker++;
  +}
  +if (!candidate) {
  +/* All the workers are in error state or disabled.
  + * If the balancer has a timeout wait.
  + */
  +#if APR_HAS_THREADS
  +if (balancer-timeout) {
  +/* XXX: This can perhaps be build using some 
  + * smarter mechanism, like tread_cond.
  + * But since the statuses can came from 
  + * different childs, use the provided algo. 
  + */
  +apr_interval_time_t timeout = balancer-timeout;
  +apr_interval_time_t step, tval = 0;
  +balancer-timeout = 0;
  +step = timeout / 100;
  +while (tval  timeout) {
  +apr_sleep(step);
  +/* Try again */
  +if ((candidate = find_best_worker(balancer, r)))
  +break;
  +tval += step;
  +}
  +/* restore the timeout */
  +balancer-timeout = timeout;
  +}
  +#endif
  +}
  +else {
  +/* We have at least one candidate that is not in
  + * error state or disabled.
  + * Now calculate the appropriate one 
  + */
  +for (i = 0; i  balancer-workers-nelts; i++) {
  +/* If the worker is not error state
  + * or not in disabled mode
  + */
  +if (worker-w-status  2) {
  +/* 1. Find the worker with higher lbstatus.
  + * Lbstatus is of higher importance then
  + * the number of empty slots.
  + */
  +if (worker-lbstatus  candidate-lbstatus) {
  +candidate = worker;
  +}
  +}
  +worker++;
  +}
  +/* XXX: The lbfactor can be update using bytes transfered
  + * Right now, use the round-robin scheme
  + */
  +candidate-lbstatus += candidate-lbfactor;
  +if (candidate-lbstatus = total_status)
  +candidate-lbstatus = candidate-lbfactor;
  +}
  +return candidate;
  +}
  +
   static int proxy_balancer_pre_request(proxy_worker **worker,
 proxy_balancer **balancer,
 request_rec *r,
  @@ -140,6 +224,7 @@
   char *route;
   apr_status_t rv;
   
  +*worker = NULL;
   /* Spet 1: check if the url is for us */
   if (!(*balancer = ap_proxy_get_balancer(r-pool, conf, *url)))
   return DECLINED;
  @@ -155,6 +240,10 @@
   return HTTP_SERVICE_UNAVAILABLE;
   }
   }
  +else {
  +/* We have a sticky load balancer */
  +*worker = runtime-w;
  +}
   /* Lock the LoadBalancer
* XXX: perhaps we need the process lock here
*/
  @@ -163,6 +252,23 @@
proxy_balancer_pre_request: lock);
   return DECLINED;
   }
  +if 

cvs commit: jakarta-tomcat-connectors/ajp/proxy proxy_balancer.c

2004-08-09 Thread mturk
mturk   2004/08/09 03:10:24

  Modified:ajp/proxy proxy_balancer.c
  Log:
  The lbstatus needs to be updated for every worker, not just the candidate.
  
  Revision  ChangesPath
  1.3   +20 -8 jakarta-tomcat-connectors/ajp/proxy/proxy_balancer.c
  
  Index: proxy_balancer.c
  ===
  RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/proxy_balancer.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- proxy_balancer.c  9 Aug 2004 09:55:47 -   1.2
  +++ proxy_balancer.c  9 Aug 2004 10:10:24 -   1.3
  @@ -134,7 +134,7 @@
 request_rec *r)
   {
   int i;
  -double total_status = 0.0;
  +double total_factor = 0.0;
   proxy_runtime_worker *worker = (proxy_runtime_worker *)balancer-workers-elts;
   proxy_runtime_worker *candidate = NULL;
   
  @@ -153,7 +153,11 @@
   if (worker-w-cp-nfree  candidate-w-cp-nfree)
   candidate = worker;
   }
  -total_status += worker-lbstatus;
  +/* Total factor should allways be 100.
  + * This is for cases when worker is in error state.
  + * It will force the even request distribution
  + */
  +total_factor += worker-lbfactor;
   }
   worker++;
   }
  @@ -204,12 +208,20 @@
   }
   worker++;
   }
  -/* XXX: The lbfactor can be update using bytes transfered
  - * Right now, use the round-robin scheme
  - */
  -candidate-lbstatus += candidate-lbfactor;
  -if (candidate-lbstatus = total_status)
  -candidate-lbstatus = candidate-lbfactor;
  +for (i = 0; i  balancer-workers-nelts; i++) {
  +/* If the worker is not error state
  + * or not in disabled mode
  + */
  +if (worker-w-status  2) {
  +/* XXX: The lbfactor can be update using bytes transfered
  + * Right now, use the round-robin scheme
  + */
  +worker-lbstatus += worker-lbfactor;
  +if (worker-lbstatus = total_factor)
  +worker-lbstatus = worker-lbfactor;
  +}
  +worker++;
  +}
   }
   return candidate;
   }
  
  
  

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



cvs commit: jakarta-tomcat-connectors/ajp/proxy proxy_balancer.c

2004-08-09 Thread mturk
mturk   2004/08/09 08:08:28

  Modified:ajp/proxy proxy_balancer.c
  Log:
  Add rewrite url function and calcute lbstatuses when session worker is elected.
  
  Revision  ChangesPath
  1.4   +48 -10jakarta-tomcat-connectors/ajp/proxy/proxy_balancer.c
  
  Index: proxy_balancer.c
  ===
  RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/proxy_balancer.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- proxy_balancer.c  9 Aug 2004 10:10:24 -   1.3
  +++ proxy_balancer.c  9 Aug 2004 15:08:28 -   1.4
  @@ -97,7 +97,7 @@
   int i;
   proxy_runtime_worker *worker = (proxy_runtime_worker *)balancer-workers-elts;
   for (i = 0; i  balancer-workers-nelts; i++) {
  -if (worker-route  strcmp(worker-route, route) == 0) {
  +if (worker-w-route  strcmp(worker-w-route, route) == 0) {
   return worker;
   }
   worker++;
  @@ -120,8 +120,13 @@
   proxy_runtime_worker *worker =  find_route_worker(balancer, *route);
   /* TODO: make worker status codes */
   /* See if we have a redirection route */
  -if (worker  worker-w-status  2  worker-redirect)
  -worker = find_route_worker(balancer, worker-redirect);
  +if (worker  !PROXY_WORKER_IS_USABLE(worker-w)) {
  +if (worker-w-redirect)
  +worker = find_route_worker(balancer, worker-w-redirect);
  +/* Check if the redirect worker is usable */
  +if (worker  !PROXY_WORKER_IS_USABLE(worker-w))
  +worker = NULL;
  +}
   else
   worker = NULL;
   return worker;
  @@ -145,7 +150,7 @@
*/
   
   /* TODO: read the scoreboard status */
  -if (worker-w-status  2) {
  +if (PROXY_WORKER_IS_USABLE(worker-w)) {
   if (!candidate)
   candidate = worker;
   else {
  @@ -197,7 +202,7 @@
   /* If the worker is not error state
* or not in disabled mode
*/
  -if (worker-w-status  2) {
  +if (PROXY_WORKER_IS_USABLE(worker-w)) {
   /* 1. Find the worker with higher lbstatus.
* Lbstatus is of higher importance then
* the number of empty slots.
  @@ -212,7 +217,7 @@
   /* If the worker is not error state
* or not in disabled mode
*/
  -if (worker-w-status  2) {
  +if (PROXY_WORKER_IS_USABLE(worker-w)) {
   /* XXX: The lbfactor can be update using bytes transfered
* Right now, use the round-robin scheme
*/
  @@ -226,12 +231,32 @@
   return candidate;
   }
   
  +static int rewrite_url(request_rec *r, proxy_worker *worker,
  +char **url)
  +{
  +const char *path = strchr(*url, '/');
  +
  +/* we break the URL into host, port, uri */
  +if (!worker) {
  +return ap_proxyerror(r, HTTP_BAD_REQUEST, apr_pstrcat(r-pool,
  + missing worker. URI cannot be parsed: , *url,
  + NULL));
  +}
  +
  +*url = apr_pstrcat(r-pool, worker-name, path, NULL);
  +
  +ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r-server,
  + proxy: BALANCER rewriting to %s, *url);
  +   
  +return OK;
  +}
  +
   static int proxy_balancer_pre_request(proxy_worker **worker,
 proxy_balancer **balancer,
 request_rec *r,
 proxy_server_conf *conf, char **url)
   {
  -int access_status = OK;
  +int access_status;
   proxy_runtime_worker *runtime;
   char *route;
   apr_status_t rv;
  @@ -253,8 +278,22 @@
   }
   }
   else {
  +int i;
  +proxy_runtime_worker *workers;
   /* We have a sticky load balancer */
   *worker = runtime-w;
  +/* Update the workers status 
  + * so that even session routes get
  + * into account.
  + */
  +workers = (proxy_runtime_worker *)(*balancer)-workers-elts;
  +for (i = 0; i  (*balancer)-workers-nelts; i++) {
  +/* For now assume that all workers are OK */
  +workers-lbstatus += workers-lbfactor;
  +if (workers-lbstatus = 100.0)
  +workers-lbstatus = workers-lbfactor;
  +workers++;
  +}
   }
   /* Lock the LoadBalancer
* XXX: perhaps we need the process lock here
  @@ -274,8 +313,6 @@
   PROXY_BALANCER_UNLOCK(*balancer);
   return HTTP_SERVICE_UNAVAILABLE;
   }
  -/* TODO: rewrite the url to coresponds to worker scheme */
  -
   *worker = runtime-w;
   }