Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Eugene Shen
erp5
Commits
05a213ef
Commit
05a213ef
authored
Apr 06, 2017
by
Eugene Shen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Thoroughly validate polling logic
parent
2b146ccf
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
92 additions
and
40 deletions
+92
-40
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_box_js.js
...plateItem/web_page_module/gadget_erp5_page_chat_box_js.js
+92
-40
No files found.
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_box_js.js
View file @
05a213ef
...
...
@@ -212,13 +212,12 @@
// i.e. {quiet_room: 3, busy_room: 429}
message_count_dict
:
{},
// a dict of room names to their delayRefresh promise queues
// i.e. {room: new RSVP.Queue().push(function () { return ... })}
// a dict of room names to an object with keys corresponding to
// their delayRefresh promise queues, i.e. queue: new RSVP.Queue()
// their POLL_DELAy_LIST indices, i.e. index: 3, and
// whether each is currently running refreshChat, i.e. lock: true
delay_refresh_dict
:
{},
// a dict of room names to whether each is currently running refreshChat
current_refresh_dict
:
{},
// true to use alert_icon_url, false to use default_icon_url
favicon_alert
:
false
,
alert_icon_url
:
"
https://pricespy.co.nz/favicon.ico
"
,
...
...
@@ -240,7 +239,7 @@
.
declareAcquiredMethod
(
"
getSetting
"
,
"
getSetting
"
)
/* Join a new room
room
.
/* Join a new room.
* This function is acquired by gadget_erp5_chat_room.
* Parameters:
* - room: the name of the room to join
...
...
@@ -377,9 +376,6 @@
"
jio_storage_description
"
,
"
jio_configurator
"
,
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
gadget
.
updateHeader
({
page_title
:
"
OfficeJS Chat
"
});
})
.
push
(
function
()
{
return
gadget
.
updateHeader
({
page_title
:
"
OfficeJS Chat
"
});
})
...
...
@@ -423,8 +419,7 @@
gadget
.
state
.
unread_room_dict
[
gadget
.
state
.
room
]
=
false
;
return
gadget
.
changeState
({
refresh_chat
:
true
,
favicon_alert
:
false
,
update
:
true
favicon_alert
:
false
});
};
return
gadget
.
createRoom
(
user_email
);
...
...
@@ -473,9 +468,16 @@
default_jio_type
:
gadget
.
state
.
default_jio_type
,
default_erp5_url
:
gadget
.
state
.
default_erp5_url
,
default_dav_url
:
gadget
.
state
.
default_dav_url
,
// XXX store room in description because description is
// indexed in ERP5, and only indexed properties can be queried
query
:
{
query
:
'
portal_type: "Text Post" AND room: "
'
+
room
+
'
"
'
,
limit
:
[
0
,
JIO_QUERY_MAX_LIMIT
]
query
:
'
portal_type: "Text Post" AND description: "
'
+
room
+
'
"
'
,
limit
:
[
0
,
JIO_QUERY_MAX_LIMIT
],
select_list
:
[
"
content
"
],
sort_on
:
[
[
"
date_ms
"
,
"
ascending
"
],
[
"
content
"
,
"
ascending
"
]
]
}
});
})
...
...
@@ -485,8 +487,11 @@
.
push
(
function
()
{
gadget
.
state
.
message_list_dict
[
room
]
=
[];
gadget
.
state
.
message_count_dict
[
room
]
=
0
;
gadget
.
state
.
current_refresh_dict
[
room
]
=
false
;
gadget
.
state
.
delay_refresh_dict
[
room
]
=
new
RSVP
.
Queue
();
gadget
.
state
.
delay_refresh_dict
[
room
]
=
{
queue
:
new
RSVP
.
Queue
(),
index
:
0
,
lock
:
false
};
gadget
.
state
.
id_to_name
[
"
chat-contact-
"
+
nameToId
(
room
)]
=
room
;
return
gadget
.
changeState
({
room
:
room
,
is_chat
:
false
});
});
...
...
@@ -505,7 +510,7 @@
.
declareMethod
(
"
changeRoom
"
,
function
(
room
)
{
var
gadget
=
this
;
if
(
gadget
.
state
.
message_
list_dict
[
room
].
length
>
0
)
{
if
(
gadget
.
state
.
message_
count_dict
[
room
]
>
0
)
{
return
gadget
.
changeState
({
room
:
room
,
is_chat
:
true
});
}
return
gadget
.
changeState
({
room
:
room
,
is_chat
:
false
,
update
:
true
});
...
...
@@ -534,7 +539,10 @@
gadget
.
state
.
unread_room_dict
[
param_dict
.
room
]
=
false
;
return
gadget
.
storeArchive
(
message
)
.
push
(
function
()
{
return
gadget
.
changeState
({
refresh_chat
:
true
,
favicon_alert
:
false
});
return
gadget
.
changeState
({
refresh_chat
:
true
,
favicon_alert
:
false
});
});
})
...
...
@@ -581,6 +589,7 @@
author
:
message
.
name
,
date_ms
:
getTime
(
message
),
room
:
message
.
room
,
description
:
message
.
room
,
content
:
JSON
.
stringify
(
message
)
}]);
});
...
...
@@ -593,7 +602,7 @@
* - poll_delay_index: the index in POLL_DELAY_LIST of
* the time in milliseconds to wait before refreshing again
* Requirements:
* - gadget.state.delay_refresh_dict[room] has new RSVP.Queue() in it
* - gadget.state.delay_refresh_dict[room]
.queue
has new RSVP.Queue() in it
* Effects:
* - call refreshChat and wait a while before calling it again
*/
...
...
@@ -602,21 +611,60 @@
var
gadget
=
this
;
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
// the last element in POLL_DELAY_LIST is the maximum polling interval
if
(
poll_delay_index
>=
POLL_DELAY_LIST
.
length
)
{
poll_delay_index
=
POLL_DELAY_LIST
.
length
-
1
;
}
// do not wait for refreshChat to finish before starting the delay
// do not wait for refreshChat() to finish before starting the delay
// otherwise, the true delay would depend on the time of refreshChat()
return
RSVP
.
all
([
RSVP
.
delay
(
POLL_DELAY_LIST
[
poll_delay_index
]),
gadget
.
refreshChat
(
room
)
]);
})
/* there are four main cases:
* 1. the current polling interval is shorter than the stored interval,
* and refreshChat() is being executed with the stored interval
* - should cancel and overwrite the longer interval
* - the longer interval is both stored and being run
* - safe to cancel because refreshChat() is executed
* with the shorter interval immediately afterwards
* - so, cancel the longer interval, then overwrite it
* 2. the current polling interval is shorter than the stored interval,
* and refreshChat() is not being executed with the stored interval
* - should cancel and overwrite the longer interval
* - the longer interval is only being stored, not being run
* - so, overwrite it
* 3. the current polling interval is the same as the stored interval
* - should cancel and overwrite the longer interval
* - dangerous to cancel because the currently executing code in
* delayRefresh() could have been called by the stored interval!
* - so, overwrite it and do not cancel it, even if it is being run
* 4. the current polling interval is longer than the stored interval
* - should cancel and overwrite the longer interval
* - the longer interval is neither stored nor being run
* - so, do nothing
*/
.
push
(
function
()
{
gadget
.
state
.
delay_refresh_dict
[
room
].
cancel
();
gadget
.
state
.
delay_refresh_dict
[
room
]
=
new
RSVP
.
Queue
()
if
(
poll_delay_index
<
gadget
.
state
.
delay_refresh_dict
[
room
].
index
&&
!
gadget
.
state
.
delay_refresh_dict
[
room
].
lock
)
{
gadget
.
state
.
delay_refresh_dict
[
room
].
queue
.
cancel
();
}
if
(
poll_delay_index
<=
gadget
.
state
.
delay_refresh_dict
[
room
].
index
)
{
gadget
.
state
.
delay_refresh_dict
[
room
]
=
{
// delayRefresh() is immediately called after this line
// and can be cancelled to overwrite longer intervals
queue
:
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
gadget
.
delayRefresh
(
room
,
poll_delay_index
+
1
);
});
}),
// increase the polling interval over time
index
:
poll_delay_index
+
1
,
// only refreshChat() should modify the locks
lock
:
gadget
.
state
.
delay_refresh_dict
[
room
].
lock
};
}
});
})
...
...
@@ -644,10 +692,12 @@
// lock so that at most one refreshChat() is running at any time
// multiple calls to repair() results in unmanageable duplication
if
(
gadget
.
state
.
current_refresh_dict
[
room
])
{
// atomic because JavaScript is single threaded,
// so nothing else can run between the following four lines
if
(
gadget
.
state
.
delay_refresh_dict
[
room
].
lock
)
{
return
;
}
gadget
.
state
.
current_refresh_dict
[
room
]
=
true
;
gadget
.
state
.
delay_refresh_dict
[
room
].
lock
=
true
;
return
gadget
.
getDeclaredGadget
(
"
room-gadget-
"
+
room
)
.
push
(
function
(
sub_gadget
)
{
...
...
@@ -680,6 +730,7 @@
j
=
0
;
for
(
i
=
0
;
i
<
result_list
.
data
.
total_rows
;
i
+=
1
)
{
message
=
JSON
.
parse
(
result_list
.
data
.
rows
[
i
].
value
.
content
);
if
(
typeof
message
===
"
object
"
)
{
while
(
j
<
old_list
.
length
&&
getTime
(
old_list
[
j
])
<
getTime
(
message
))
{
new_list
.
push
(
old_list
[
j
]);
...
...
@@ -692,6 +743,7 @@
}
new_list
.
push
(
message
);
}
}
while
(
j
<
old_list
.
length
)
{
new_list
.
push
(
old_list
[
j
]);
j
+=
1
;
...
...
@@ -709,9 +761,9 @@
// release the lock no matter what errors occur
.
push
(
function
()
{
gadget
.
state
.
current_refresh_dict
[
room
]
=
false
;
gadget
.
state
.
delay_refresh_dict
[
room
].
lock
=
false
;
},
function
()
{
gadget
.
state
.
current_refresh_dict
[
room
]
=
false
;
gadget
.
state
.
delay_refresh_dict
[
room
].
lock
=
false
;
});
})
...
...
@@ -857,11 +909,11 @@
var
promise_list
=
[],
room
;
for
(
room
in
gadget
.
state
.
message_list_dict
)
{
if
(
gadget
.
state
.
message_list_dict
.
hasOwnProperty
(
room
)
&&
gadget
.
state
.
message_
list_dict
[
room
].
length
>
0
)
{
&&
gadget
.
state
.
message_
count_dict
[
room
]
>
0
)
{
promise_list
.
push
(
gadget
.
deployMessage
({
name
:
gadget
.
state
.
name
,
content
:
gadget
.
state
.
name
+
"
has quit.
"
,
room
:
room
,
content
:
gadget
.
state
.
name
+
"
has quit.
"
,
color
:
"
orange
"
}));
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment