Remove subject IDs and improve request handling
This commit is contained in:
parent
9588e88b93
commit
68c55573de
@ -16,12 +16,12 @@ namespace StudySystemClient {
|
|||||||
scrolled_window.add_css_class("card-container");
|
scrolled_window.add_css_class("card-container");
|
||||||
|
|
||||||
var activities = new Activity[] {
|
var activities = new Activity[] {
|
||||||
{ 2, "Linguistics", ActivityType.EXERCISES },
|
{ "Linguistics", ActivityType.EXERCISES },
|
||||||
{ 1, "Cybernetics", ActivityType.EXERCISES },
|
{ "Cybernetics", ActivityType.EXERCISES },
|
||||||
{ 2, "Linguistics", ActivityType.READING },
|
{ "Linguistics", ActivityType.READING },
|
||||||
{ 0, "Physics", ActivityType.READING },
|
{ "Physics", ActivityType.READING },
|
||||||
{ 1, "Cybernetics", ActivityType.READING },
|
{ "Cybernetics", ActivityType.READING },
|
||||||
{ 0, "Physics", ActivityType.EXERCISES },
|
{ "Physics", ActivityType.EXERCISES },
|
||||||
};
|
};
|
||||||
foreach (var activity in activities) {
|
foreach (var activity in activities) {
|
||||||
var card = new ActivityCard(client, activity);
|
var card = new ActivityCard(client, activity);
|
||||||
@ -42,7 +42,7 @@ namespace StudySystemClient {
|
|||||||
var text = new Gtk.Box(Gtk.Orientation.VERTICAL, 6);
|
var text = new Gtk.Box(Gtk.Orientation.VERTICAL, 6);
|
||||||
text.hexpand = true;
|
text.hexpand = true;
|
||||||
|
|
||||||
var subject = new Gtk.Label(activity.subject_name);
|
var subject = new Gtk.Label(activity.subject);
|
||||||
subject.halign = Gtk.Align.START;
|
subject.halign = Gtk.Align.START;
|
||||||
subject.add_css_class("activity-subject");
|
subject.add_css_class("activity-subject");
|
||||||
text.append(subject);
|
text.append(subject);
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
namespace StudySystemClient {
|
namespace StudySystemClient {
|
||||||
public struct Activity {
|
public struct Activity {
|
||||||
public int subject_id;
|
public string subject;
|
||||||
public string subject_name;
|
|
||||||
public ActivityType type;
|
public ActivityType type;
|
||||||
public double priority;
|
public double priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ActivityType {
|
public enum ActivityType {
|
||||||
EXERCISES,
|
READING = 0,
|
||||||
READING;
|
EXERCISES = 1;
|
||||||
|
|
||||||
public string to_string() {
|
public string to_string() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
|
@ -41,11 +41,11 @@ namespace StudySystemClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void log_session(int subject_id, ActivityType type,
|
public async void log_session(string subject, ActivityType type,
|
||||||
int minutes) throws ClientError {
|
int minutes) throws ClientError {
|
||||||
var timestamp = new DateTime.now_utc().to_unix();
|
var timestamp = new DateTime.now_utc().to_unix();
|
||||||
var request = new Request.LogSession(subject_id, type,
|
var request
|
||||||
timestamp, minutes);
|
= new Request.LogSession(subject, type, timestamp, minutes);
|
||||||
var response = yield connection.send(request);
|
var response = yield connection.send(request);
|
||||||
if (response is Response.Ack) {
|
if (response is Response.Ack) {
|
||||||
return;
|
return;
|
||||||
|
@ -39,11 +39,11 @@ namespace StudySystemClient.Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class LogSession : Body {
|
public class LogSession : Body {
|
||||||
public LogSession(int subject_id, ActivityType type,
|
public LogSession(string subject, ActivityType type,
|
||||||
int64 timestamp, int minutes)
|
int64 timestamp, int minutes)
|
||||||
{
|
{
|
||||||
var fields = new Der.Datum[] {
|
var fields = new Der.Datum[] {
|
||||||
new Der.Integer(subject_id),
|
new Der.Utf8String(subject),
|
||||||
new Der.Enumerated((int)type),
|
new Der.Enumerated((int)type),
|
||||||
new Der.Integer(timestamp),
|
new Der.Integer(timestamp),
|
||||||
new Der.Integer(minutes),
|
new Der.Integer(minutes),
|
||||||
|
@ -127,20 +127,17 @@ namespace StudySystemClient.Response {
|
|||||||
throws DecodeError {
|
throws DecodeError {
|
||||||
if (datum is Der.Sequence) {
|
if (datum is Der.Sequence) {
|
||||||
var fields = datum.value;
|
var fields = datum.value;
|
||||||
if (fields.length < 4) {
|
if (fields.length < 3) {
|
||||||
throw new DecodeError.INVALID_BODY(
|
throw new DecodeError.INVALID_BODY(
|
||||||
"Too few fields in Activity: %u (expected 4)",
|
"Too few fields in Activity: %u (expected 3)",
|
||||||
fields.length);
|
fields.length);
|
||||||
}
|
}
|
||||||
var subject_id = get_int("Activity.subjectId", fields[0]);
|
var subject = get_string("Activity.subject", fields[0]);
|
||||||
var subject_name
|
|
||||||
= get_string("Activity.subjectName", fields[1]);
|
|
||||||
var activity_type
|
var activity_type
|
||||||
= get_activity_type("Activity.type", fields[2]);
|
= get_activity_type("Activity.type", fields[1]);
|
||||||
var int_priority = get_int("Activity.priority", fields[3]);
|
var priority_int = get_int("Activity.priority", fields[2]);
|
||||||
var priority = (double)int_priority / 100.0;
|
var priority = (double)priority_int / 100.0;
|
||||||
return { subject_id, subject_name, activity_type, priority };
|
return { subject, activity_type, priority };
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new DecodeError.INVALID_BODY(
|
throw new DecodeError.INVALID_BODY(
|
||||||
"Activity was not a SEQUENCE");
|
"Activity was not a SEQUENCE");
|
||||||
|
@ -65,7 +65,7 @@ namespace StudySystemClient {
|
|||||||
public class SessionFactory {
|
public class SessionFactory {
|
||||||
private const string CA_FILENAME = "/ca.pem";
|
private const string CA_FILENAME = "/ca.pem";
|
||||||
private const string CERT_FILENAME = "/client.pem";
|
private const string CERT_FILENAME = "/client.pem";
|
||||||
private const uint TIMEOUT_S = 1;
|
private const uint TIMEOUT_S = 5;
|
||||||
|
|
||||||
private InetSocketAddress host;
|
private InetSocketAddress host;
|
||||||
private TlsCertificate cert;
|
private TlsCertificate cert;
|
||||||
|
@ -6,7 +6,7 @@ ActivityType ::= ENUMERATED {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Session ::= SEQUENCE {
|
Session ::= SEQUENCE {
|
||||||
subjectId INTEGER,
|
subject UTF8String,
|
||||||
type ActivityType,
|
type ActivityType,
|
||||||
timestamp INTEGER,
|
timestamp INTEGER,
|
||||||
minutes INTEGER
|
minutes INTEGER
|
||||||
@ -24,8 +24,7 @@ Request ::= SEQUENCE {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Activity ::= SEQUENCE {
|
Activity ::= SEQUENCE {
|
||||||
subjectId INTEGER,
|
subject UTF8String,
|
||||||
subjectName UTF8String,
|
|
||||||
type ActivityType,
|
type ActivityType,
|
||||||
priority INTEGER
|
priority INTEGER
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,8 @@ start_link(Socket) ->
|
|||||||
|
|
||||||
init(Socket) ->
|
init(Socket) ->
|
||||||
ok = ssl:setopts(Socket, [{active, true}]),
|
ok = ssl:setopts(Socket, [{active, true}]),
|
||||||
{ok, #{socket => Socket}}.
|
process_flag(trap_exit, true),
|
||||||
|
{ok, #{socket => Socket, transactions => #{}}}.
|
||||||
|
|
||||||
handle_call(_Request, _From, State) ->
|
handle_call(_Request, _From, State) ->
|
||||||
{reply, ok, State}.
|
{reply, ok, State}.
|
||||||
@ -21,21 +22,28 @@ handle_call(_Request, _From, State) ->
|
|||||||
handle_cast(_Msg, State) ->
|
handle_cast(_Msg, State) ->
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
|
||||||
handle_info({ssl, Socket, Data}, State) ->
|
handle_info({ssl, Socket, Data}, State = #{transactions := Transactions}) ->
|
||||||
case 'StudySystemProtocol':decode('Request', Data) of
|
case 'StudySystemProtocol':decode('Request', Data) of
|
||||||
{ok, {'Request', TransactionId, RequestBody}} ->
|
{ok, {'Request', TransactionId, RequestBody}} ->
|
||||||
ResponseBody = map_request(RequestBody),
|
Pid = spawn_link(fun() -> handle_request(RequestBody) end),
|
||||||
{ok, Encoded} = 'StudySystemProtocol':encode(
|
NewTransactions = maps:put(Pid, TransactionId, Transactions),
|
||||||
'Response',
|
{noreply, State#{transactions := NewTransactions}};
|
||||||
{'Response', TransactionId, ResponseBody}),
|
|
||||||
ok = ssl:send(Socket, Encoded);
|
|
||||||
{error, {asn1, _Reason}} ->
|
{error, {asn1, _Reason}} ->
|
||||||
{ok, Encoded} = 'StudySystemProtocol':encode(
|
send(Socket, -1, {error, invalidRequest}),
|
||||||
'Response',
|
{noreply, State}
|
||||||
{'Response', -1, {error, invalidRequest}}),
|
end;
|
||||||
ok = ssl:send(Socket, Encoded)
|
handle_info({'EXIT', Pid, Reason},
|
||||||
end,
|
State = #{socket := Socket, transactions := Transactions})
|
||||||
{noreply, State};
|
when is_map_key(Pid, Transactions) ->
|
||||||
|
TransactionId = maps:get(Pid, Transactions),
|
||||||
|
Response = case Reason of
|
||||||
|
{response, Value} -> Value;
|
||||||
|
_ ->
|
||||||
|
io:format("Request handling error: ~p~n", [Reason]),
|
||||||
|
{error, serverError}
|
||||||
|
end,
|
||||||
|
send(Socket, TransactionId, Response),
|
||||||
|
{noreply, State#{transactions := maps:remove(Pid, Transactions)}};
|
||||||
handle_info({ssl_closed, _Socket}, State) ->
|
handle_info({ssl_closed, _Socket}, State) ->
|
||||||
{stop, normal, State};
|
{stop, normal, State};
|
||||||
handle_info({ssl_error, _Socket, _Reason}, State) ->
|
handle_info({ssl_error, _Socket, _Reason}, State) ->
|
||||||
@ -49,7 +57,17 @@ terminate(_Reason, #{socket := Socket}) ->
|
|||||||
code_change(_OldVsn, State, _Extra) ->
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
{ok, State}.
|
{ok, State}.
|
||||||
|
|
||||||
|
handle_request(Request) ->
|
||||||
|
timer:kill_after(500),
|
||||||
|
exit(map_request(Request)).
|
||||||
|
|
||||||
map_request({ping, 'NULL'}) ->
|
map_request({ping, 'NULL'}) ->
|
||||||
{ack, 'NULL'};
|
{response, {ack, 'NULL'}};
|
||||||
map_request(_) ->
|
map_request(_) ->
|
||||||
{error, invalidRequest}.
|
{response, {error, invalidArguments}}.
|
||||||
|
|
||||||
|
send(Socket, TransactionId, Response) ->
|
||||||
|
{ok, Encoded} = 'StudySystemProtocol':encode(
|
||||||
|
'Response',
|
||||||
|
{'Response', TransactionId, Response}),
|
||||||
|
ok = ssl:send(Socket, Encoded).
|
||||||
|
@ -11,8 +11,8 @@ start_link() ->
|
|||||||
|
|
||||||
init([]) ->
|
init([]) ->
|
||||||
SupFlags = #{strategy => simple_one_for_one,
|
SupFlags = #{strategy => simple_one_for_one,
|
||||||
intensity => 10,
|
intensity => 5,
|
||||||
period => 1},
|
period => 10},
|
||||||
ChildSpec = #{id => session_server,
|
ChildSpec = #{id => session_server,
|
||||||
start => {session_server, start_link, []},
|
start => {session_server, start_link, []},
|
||||||
restart => temporary,
|
restart => temporary,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user