collect_users._pike
Go to the documentation of this file.
1 /* Copyright (C) 2000-2005 Thomas Bopp, Thorsten Hampel, Ludger Merkens
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * $Id: collect_users.pike,v 1.1 2008/03/31 13:39:57 exodusd Exp $
18  */
19 inherit "/kernel/module";
20 #include <macros.h>
21 #include <events.h>
22 #include <attributes.h>
23 #include <coal.h>
24 #include <database.h>
25 //! checks active users and possible moves them home
26 class collect_users : public module{
27 public:
28 
29 
30 
31 
32 
33 
34 
35 //#define DEBUG_COLLECT
36 
37 #ifdef DEBUG_COLLECT
38 #define LOG_COLLECT(s, args...) werror("Collecting: " + s+ "\n", args)
39 #else
40 #define LOG_COLLECT(s, args...)
41 #endif
42 
43  Thread.Queue userQueue = Thread.Queue();
44 
45 void load_module()
46 {
47  add_global_event(EVENT_LOGIN, user_login, PHASE_NOTIFY);
48  start_thread(collect);
49 }
50 
51 void user_login(object obj, object user, int feature, int prev_features)
52 {
53  LOG_COLLECT("User %O logged in ...", user);
54  userQueue->write(user);
55 }
56 
57 /**
58  * Check if a user needs cleanup and should be moved into her
59  * workroom.
60  *
61  * @param object user - the user to check.
62  *
63  */
64 void check_user_cleanup(object user)
65 {
66  userQueue->write(user);
67 }
68 
69 void check_users_cleanup(array users)
70 {
71  foreach(users, object u)
72  if ( objectp(u) )
73  userQueue->write(u);
74 }
75 
76 protected:
77  int check_user(object user)
78 {
79  LOG_COLLECT("Checking user %O", user);
80  if ( !stringp(user->get_identifier()) )
81  return 0;
82  if ( user->get_status() == 0 ) {
83  if ( user->get_environment() != user->query_attribute(USER_WORKROOM) ){
84  LOG_COLLECT("Collect: Moving user %s", user->get_identifier());
85  object wr = user->query_attribute(USER_WORKROOM);
86  LOG_COLLECT("Found Workroom %O", wr);
87  if ( objectp(wr) ) {
88  user->move(wr);
89  LOG_COLLECT("Moved !");
90  }
91  }
92  return 0;
93  }
94  return 1;
95 }
96 
97 public:
98 
99 protected:
100  void collect()
101 {
102  while ( 1 ) {
103  mixed err = catch {
104  LOG_COLLECT(" Checking users ...");
105  object user;
106  array check_users;
107  check_users = ({ });
108  while ( userQueue->size() > 0 ) {
109  user = userQueue->read();
110  if ( search(check_users, user) == -1 &&
111  check_user(user) )
112  check_users += ({ user });
113  }
114  foreach ( check_users, user)
115  userQueue->write(user);
116  // also check idle connections!
117 
118  foreach ( master()->get_users(), object socket ) {
119  if ( !objectp(socket) ) continue;
120 
121  // do not close service connections
122  if ( functionp(socket->get_user_object) &&
123  socket->get_user_object() == USER("service") )
124  continue;
125 
126  if ( functionp(socket->get_last_response) )
127  {
128  int t = time() - socket->get_last_response();
129  if ( t > COAL_TIMEOUT ) {
130  if ( !functionp(socket->get_ip) )
131  werror("Socket without IP function !");
132  mixed e = catch(socket->close_connection());
133  }
134  }
135  }
136  };
137  if ( err != 0 )
138  FATAL("Error on collect_users():\n %s\n%s",
139  err[0], describe_backtrace(err[1]));
140 #ifdef DEBUG_COLLECT
141  sleep(10);
142 #else
143  sleep(300);
144 #endif
145  }
146 }
147 
148 public:
149 
150 string get_identifier() { return "collect_users"; }
151 
152 
153 
154 };