Skip to content

Commit

Permalink
client: update keyword handling
Browse files Browse the repository at this point in the history
new keyword model:
- keywords as identified by integer IDs
- instead of being treated as opaque data,
    the keyword XML is now parsed by the client.

This is a first step: pass keywords from AM to client to scheduler,
so that they can be used in job filtering.
Displaying keywords in the client will come later.
  • Loading branch information
davidpanderson committed Jul 16, 2017
1 parent daee3b6 commit 5add5fd
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 44 deletions.
37 changes: 13 additions & 24 deletions client/acct_mgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ void AM_ACCOUNT::handle_no_rsc(const char* name, bool value) {
no_rsc[i] = value;
}

// parse account from AM reply
//
int AM_ACCOUNT::parse(XML_PARSER& xp) {
char buf[256];
bool btemp;
Expand Down Expand Up @@ -333,12 +335,6 @@ int AM_ACCOUNT::parse(XML_PARSER& xp) {
abort_not_started.set(btemp);
continue;
}
if (xp.parse_string("sci_keywords", sci_keywords)) {
continue;
}
if (xp.parse_string("loc_keywords", loc_keywords)) {
continue;
}
if (log_flags.unparsed_xml) {
msg_printf(NULL, MSG_INFO,
"[unparsed_xml] AM_ACCOUNT: unrecognized %s", xp.parsed_tag
Expand Down Expand Up @@ -436,6 +432,10 @@ int ACCT_MGR_OP::parse(FILE* f) {
if (xp.parse_bool("no_project_notices", ami.no_project_notices)) {
continue;
}
if (xp.match_tag("user_keywords")) {
retval = ami.user_keywords.parse(xp);
if (retval) return retval;
}
if (log_flags.unparsed_xml) {
msg_printf(NULL, MSG_INFO,
"[unparsed_xml] ACCT_MGR_OP::parse: unrecognized tag <%s>",
Expand Down Expand Up @@ -655,8 +655,6 @@ void ACCT_MGR_OP::handle_reply(int http_op_retval) {
for (int j=0; j<MAX_RSC; j++) {
pp->no_rsc_ams[j] = acct.no_rsc[j];
}
pp->sci_keywords = acct.sci_keywords;
pp->loc_keywords = acct.loc_keywords;
}
} else {
// here we don't already have the project.
Expand Down Expand Up @@ -740,6 +738,7 @@ void ACCT_MGR_OP::handle_reply(int http_op_retval) {
} else {
gstate.acct_mgr_info.next_rpc_time = gstate.now + 86400;
}
gstate.acct_mgr_info.user_keywords = ami.user_keywords;
gstate.acct_mgr_info.write_info();
gstate.set_client_state_dirty("account manager RPC");
#endif
Expand Down Expand Up @@ -808,12 +807,7 @@ int ACCT_MGR_INFO::write_info() {
opaque,
no_project_notices?1:0
);
if (!sched_req_opaque.empty()) {
fprintf(f,
"<sched_req_opaque>\n<![CDATA[\n%s\n]]>\n</sched_req_opaque>\n",
sched_req_opaque.c_str()
);
}
user_keywords.write(f);
fprintf(f,
"</acct_mgr_login>\n"
);
Expand All @@ -831,14 +825,14 @@ void ACCT_MGR_INFO::clear() {
safe_strcpy(signing_key, "");
safe_strcpy(previous_host_cpid, "");
safe_strcpy(opaque, "");
sched_req_opaque.clear();
safe_strcpy(cookie_failure_url, "");
next_rpc_time = 0;
nfailures = 0;
send_gui_rpc_info = false;
password_error = false;
no_project_notices = false;
cookie_required = false;
user_keywords.clear();
}

ACCT_MGR_INFO::ACCT_MGR_INFO() {
Expand Down Expand Up @@ -875,20 +869,15 @@ int ACCT_MGR_INFO::parse_login_file(FILE* p) {
}
continue;
}
else if (xp.match_tag("sched_req_opaque")) {
char buf[65536];
retval = xp.element_contents(
"</sched_req_opaque>", buf, sizeof(buf)
);
else if (xp.parse_bool("no_project_notices", no_project_notices)) continue;
else if (xp.match_tag("user_keywords")) {
retval = user_keywords.parse(xp);
if (retval) {
msg_printf(NULL, MSG_INFO,
"error parsing <sched_req_opaque> in acct_mgr_login.xml"
"error parsing user keywords in acct_mgr_login.xml"
);
}
sched_req_opaque = string(buf);
continue;
}
else if (xp.parse_bool("no_project_notices", no_project_notices)) continue;
if (log_flags.unparsed_xml) {
msg_printf(NULL, MSG_INFO,
"[unparsed_xml] unrecognized %s in acct_mgr_login.xml",
Expand Down
10 changes: 5 additions & 5 deletions client/acct_mgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "str_replace.h"
#include "miofile.h"
#include "parse.h"
#include "keyword.h"
#include "gui_http.h"
#include "client_types.h"

Expand All @@ -39,8 +40,6 @@ struct ACCT_MGR_INFO : PROJ_AM {
// md5 of password.lowercase(login_name)
char opaque[256];
// opaque data, from the AM, to be included in future AM requests
std::string sched_req_opaque;
// opaque data to be sent in scheduler requests, in CDATA
char signing_key[MAX_KEY_LEN];
char previous_host_cpid[64];
// the host CPID sent in last RPC
Expand All @@ -61,6 +60,8 @@ struct ACCT_MGR_INFO : PROJ_AM {
// what login name and password they have been assigned
bool password_error;
bool send_rec;
// send REC in AM RPCs
USER_KEYWORDS user_keywords;

inline bool using_am() {
if (!strlen(master_url)) return false;
Expand Down Expand Up @@ -108,8 +109,7 @@ struct OPTIONAL_DOUBLE {
struct AM_ACCOUNT {
std::string url;
std::string authenticator;
std::string sci_keywords;
std::string loc_keywords;

char url_signature[MAX_SIGNATURE_LEN];
bool detach;
bool update;
Expand Down Expand Up @@ -141,7 +141,7 @@ struct ACCT_MGR_OP: public GUI_HTTP_OP {
int error_num;
ACCT_MGR_INFO ami;
// a temporary copy while doing RPC.
// CLIENT_STATE::acct_mgr_info is authoratative
// CLIENT_STATE::acct_mgr_info is authoritative
std::string error_str;
std::vector<AM_ACCOUNT> accounts;
double repeat_sec;
Expand Down
6 changes: 2 additions & 4 deletions client/cs_scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,10 +383,8 @@ int CLIENT_STATE::make_scheduler_request(PROJECT* p) {
fprintf(f, " <client_brand>%s</client_brand>\n", client_brand);
}

if (acct_mgr_info.using_am() && !acct_mgr_info.sched_req_opaque.empty()) {
fprintf(f, "<am_opaque>\n<![CDATA[\n");
fprintf(f, "%s", acct_mgr_info.sched_req_opaque.c_str());
fprintf(f, "\n]]>\n</am_opaque>\n");
if (acct_mgr_info.using_am()) {
acct_mgr_info.user_keywords.write(f);
}

fprintf(f, "</scheduler_request>\n");
Expand Down
3 changes: 0 additions & 3 deletions client/project.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ struct PROJECT : PROJ_AM {
char _project_dir[MAXPATHLEN];
char _project_dir_absolute[MAXPATHLEN];

std::string sci_keywords;
std::string loc_keywords;

// the following items come from the account file
// They are a function of the user and the project (not host)
//
Expand Down
2 changes: 1 addition & 1 deletion html/user/friend.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ function handle_cancel_confirm($user) {
) ."<p>\n"
;
show_button("friend.php?action=cancel&userid=$destid", tra("Yes"), tra("Cancel friendship"));
show_button("home.php", tra("No"), tra("Stay friends"));
show_button(USER_HOME, tra("No"), tra("Stay friends"));
echo "</ul>";
page_tail();
}
Expand Down
2 changes: 2 additions & 0 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ libfcgi_sources = \
coproc.cpp \
filesys.cpp \
hostinfo.cpp \
keyword.cpp \
md5.cpp \
md5_file.cpp \
mfile.cpp \
Expand All @@ -48,6 +49,7 @@ generic_sources = \
gui_rpc_client_ops.cpp \
gui_rpc_client_print.cpp \
hostinfo.cpp \
keyword.cpp \
md5.cpp \
md5_file.cpp \
mem_usage.cpp \
Expand Down
68 changes: 68 additions & 0 deletions lib/keyword.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2017 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.

// utility functions for keywords

#include <stdio.h>
#include <algorithm>

#include "parse.h"
#include "keyword.h"

int USER_KEYWORDS::parse(XML_PARSER& xp) {
clear();
int x;
while (!xp.get_tag()) {
if (xp.match_tag("/user_keywords")) {
return 0;
}
if (xp.parse_int("yes", x)) {
yes.push_back(x);
} else if (xp.parse_int("no", x)) {
no.push_back(x);
}
}
return ERR_XML_PARSE;
}

void USER_KEYWORDS::write(FILE* f) {
if (empty()) {
return;
}
unsigned int i;
fprintf(f, "<user_keywords>\n");
for (i=0; i<yes.size(); i++) {
fprintf(f, " <yes>%d</yes>\n", yes[i]);
}
for (i=0; i<no.size(); i++) {
fprintf(f, " <no>%d</no>\n", no[i]);
}
fprintf(f, "</user_keywords>\n");
}

double keyword_score(USER_KEYWORDS& user_keywords, JOB_KEYWORDS& job_keywords) {
double score = 0;
for (unsigned int i=0; i<job_keywords.ids.size(); i++) {
int jk = job_keywords.ids[i];
if (std::find(user_keywords.yes.begin(), user_keywords.yes.end(), jk) != user_keywords.yes.end()) {
score += 1;
} else if (std::find(user_keywords.no.begin(), user_keywords.no.end(), jk) != user_keywords.no.end()) {
return -1;
}
}
return score;
}
43 changes: 43 additions & 0 deletions lib/keyword.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2017 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.

// utility classes for keywords

#include <vector>
#include "parse.h"

struct USER_KEYWORDS {
std::vector<int> yes;
std::vector<int> no;
int parse(XML_PARSER&);
void clear() {
yes.clear();
no.clear();
}
void write(FILE*);
bool empty() {
return yes.empty() && no.empty();
}
};

struct JOB_KEYWORDS {
std::vector<int> ids;
void parse_str(char*);
// parse space-separated list
};

extern double keyword_score(USER_KEYWORDS&, JOB_KEYWORDS&);
5 changes: 4 additions & 1 deletion sched/sched_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,10 @@ const char* SCHEDULER_REQUEST::parse(XML_PARSER& xp) {
if (xp.parse_bool("client_cap_plan_class", client_cap_plan_class)) continue;
if (xp.parse_int("sandbox", sandbox)) continue;
if (xp.parse_int("allow_multiple_clients", allow_multiple_clients)) continue;
if (xp.parse_string("client_opaque", client_opaque)) continue;
if (xp.match_tag("user_keywords")) {
user_keywords.parse(xp);
continue;
}
if (xp.parse_str("client_brand", client_brand, sizeof(client_brand))) continue;

// unused or deprecated stuff follows
Expand Down
3 changes: 2 additions & 1 deletion sched/sched_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "common_defs.h"
#include "md5_file.h"
#include "coproc.h"
#include "keyword.h"

#include "edf_sim.h"

Expand Down Expand Up @@ -345,7 +346,7 @@ struct SCHEDULER_REQUEST {
// Don't modify user prefs or CPID
int last_rpc_dayofyear;
int current_rpc_dayofyear;
std::string client_opaque;
USER_KEYWORDS user_keywords;

SCHEDULER_REQUEST();
~SCHEDULER_REQUEST(){};
Expand Down
10 changes: 5 additions & 5 deletions version.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
#define BOINC_MINOR_VERSION 7

/* Release part of BOINC version number */
#define BOINC_RELEASE 2
#define BOINC_RELEASE 0

/* Release part of wrapper version number */
#define WRAPPER_RELEASE 26016

/* Release part of vboxwrapper version number */
#define VBOXWRAPPER_RELEASE 26199
#define VBOXWRAPPER_RELEASE 26197

/* String representation of BOINC version number */
#define BOINC_VERSION_STRING "7.7.2"
#define BOINC_VERSION_STRING "7.7.0"

/* Package is a pre-release (Alpha/Beta) package */
#define BOINC_PRERELEASE 1
Expand All @@ -35,13 +35,13 @@
#define PACKAGE_NAME "BOINC"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "BOINC 7.7.2"
#define PACKAGE_STRING "BOINC 7.7.0"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "boinc"

/* Define to the version of this package. */
#define PACKAGE_VERSION "7.7.2"
#define PACKAGE_VERSION "7.7.0"

#endif /* #if (defined(_WIN32) || defined(__APPLE__)) */

Expand Down

0 comments on commit 5add5fd

Please sign in to comment.