Age | Commit message (Collapse) | Author |
|
This is the final project. Now that we got rid of the web extension and
native host code, we can move the Lisp code to the root.
|
|
|
|
|
|
|
|
I used these for debugging, but they aren't relevant any more.
|
|
Makes more sense to group the option code together.
|
|
|
|
|
|
Give this check a name.
|
|
|
|
|
|
|
|
Make the config containing command line options a global variable. This
makes it easy to find out if the `--debug` flag is on in the
`websocket-send` function.
Not sure about the global variable, but seems fine for now.
|
|
|
|
We added an extra increment to the wait group in the `reload-tab`
function because when the `chrome.tabs.reload()` message succeeds, we
receive two response messages for a single one sent.
When an error comes back from the message, however, only one message is
received instead of two. We must thus decrement the wait group an extra
time to account for the lack of a second response message.
Here's what the message sequence looks like:
#<WAIT-GROUP :counter 6>
Sending: {"id":2,"sessionId":"C67B0BF214B28E1233277D01B897438E","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}}
Response: (OBJ (id . 2)
(result OBJ
(result OBJ (type . object) (subtype . error)
(className . TypeError)
(description
. TypeError: Cannot read property 'reload' of undefined
at <anonymous>:1:13)
(objectId . 1547982045888266898.197.11))
(exceptionDetails OBJ (exceptionId . 15) (text . Uncaught)
(lineNumber . 0) (columnNumber . 12) (scriptId . 1569)
(exception OBJ (type . object) (subtype . error)
(className . TypeError)
(description
. TypeError: Cannot read property 'reload' of undefined
at <anonymous>:1:13)
(objectId . 1547982045888266898.197.12))))
(sessionId . C67B0BF214B28E1233277D01B897438E))
#<WAIT-GROUP :counter 7>
Sending: {"id":2,"sessionId":"C67B0BF214B28E1233277D01B897438E","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}}
Response: (OBJ (id . 2)
(result OBJ
(result OBJ (type . object) (subtype . error)
(className . TypeError)
(description
. TypeError: Cannot read property 'reload' of undefined
at <anonymous>:1:13)
(objectId . 1547982045888266898.197.13))
(exceptionDetails OBJ (exceptionId . 16) (text . Uncaught)
(lineNumber . 0) (columnNumber . 12) (scriptId . 1569)
(exception OBJ (type . object) (subtype . error)
(className . TypeError)
(description
. TypeError: Cannot read property 'reload' of undefined
at <anonymous>:1:13)
(objectId . 1547982045888266898.197.14))))
(sessionId . C67B0BF214B28E1233277D01B897438E))
#<WAIT-GROUP :counter 8>
Sending: {"id":2,"sessionId":"C67B0BF214B28E1233277D01B897438E","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}}
Response: (OBJ (id . 2) (result OBJ (result OBJ (type . undefined)))
(sessionId . C67B0BF214B28E1233277D01B897438E))
#<WAIT-GROUP :counter 9>
|
|
We no longer have hard-coded call IDs, so these comments are outdated.
The new call ID system seems to also contribute to keeping tab reloading
working consistently, so I'm keeping it instead of going back to the
hard-coded IDs.
|
|
Finally managed to figure out why tab reloading was inconsistent. With
my added logs, I learned that _two_ responses come back from the
`chrome.tabs.reload()` message we send instead of one. This means that
the wait group gets decremented prematurely, and the program could exit
before we've transmitted the message(s).
To fix this, increment the wait group an extra time when sending the tab
reload message to account for the second message response.
Here are the logs:
One tab reloaded, one not:
#<WAIT-GROUP :counter 1>
Sending: {"id":2,"method":"Target.attachToTarget","params":{"targetId":"E1DA65BA7761486BBA9B341E5403744F","flatten":true}}
Sending: {"id":3,"method":"Target.attachToTarget","params":{"targetId":"84AFD21582910FC66AD0FB24E410BBC1","flatten":true}}
Response: (OBJ (method . Target.attachedToTarget)
(params OBJ (sessionId . C2BBFC26103DAB67ECC199C87CB38B86)
(targetInfo OBJ (targetId . E1DA65BA7761486BBA9B341E5403744F)
(type . background_page)
(title . TITLE)
(url
. chrome-extension://EXTENSION_ID/_generated_background_page.html)
(attached . T) (canAccessOpener)
(browserContextId . 29837CF1E6AC13B4FDA7DD2883E6320E))
(waitingForDebugger)))
#<WAIT-GROUP :counter 2>
Sending: {"id":1,"sessionId":"C2BBFC26103DAB67ECC199C87CB38B86","method":"Runtime.evaluate","params":{"expression":"chrome.runtime.reload()"}}
Response: (OBJ (id . 2)
(result OBJ (sessionId . C2BBFC26103DAB67ECC199C87CB38B86)))
#<WAIT-GROUP :counter 2>
Sending: {"id":2,"sessionId":"C2BBFC26103DAB67ECC199C87CB38B86","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}}
Response: (OBJ (method . Target.attachedToTarget)
(params OBJ (sessionId . 9ED44EDF0DA25CE52F21AA90EBAEF7D7)
(targetInfo OBJ (targetId . 84AFD21582910FC66AD0FB24E410BBC1)
(type . background_page)
(title . TITLE)
(url
. chrome-extension://EXTENSION_ID/_generated_background_page.html)
(attached . T) (canAccessOpener)
(browserContextId . E3DEC22E4F9847AAA674ACF4781D51A9))
(waitingForDebugger)))
#<WAIT-GROUP :counter 2>
Sending: {"id":3,"sessionId":"9ED44EDF0DA25CE52F21AA90EBAEF7D7","method":"Runtime.evaluate","params":{"expression":"chrome.runtime.reload()"}}
Response: (OBJ (id . 3)
(result OBJ (sessionId . 9ED44EDF0DA25CE52F21AA90EBAEF7D7)))
#<WAIT-GROUP :counter 2>
Sending: {"id":4,"sessionId":"9ED44EDF0DA25CE52F21AA90EBAEF7D7","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}}
Response: (OBJ (id . 1) (result OBJ (result OBJ (type . undefined)))
(sessionId . C2BBFC26103DAB67ECC199C87CB38B86))
#<WAIT-GROUP :counter 2>
Response: (OBJ (id . 3) (result OBJ (result OBJ (type . undefined)))
(sessionId . 9ED44EDF0DA25CE52F21AA90EBAEF7D7))
#<WAIT-GROUP :counter 1>
Both tabs reloaded:
#<WAIT-GROUP :counter 1>
Sending: {"id":2,"method":"Target.attachToTarget","params":{"targetId":"84AFD21582910FC66AD0FB24E410BBC1","flatten":true}}
Sending: {"id":3,"method":"Target.attachToTarget","params":{"targetId":"E1DA65BA7761486BBA9B341E5403744F","flatten":true}}
Response: (OBJ (method . Target.attachedToTarget)
(params OBJ (sessionId . A1BD02811FD42011A5325723F2D31819)
(targetInfo OBJ (targetId . 84AFD21582910FC66AD0FB24E410BBC1)
(type . background_page)
(title . TITLE)
(url
. chrome-extension://EXTENSION_ID/_generated_background_page.html)
(attached . T) (canAccessOpener)
(browserContextId . E3DEC22E4F9847AAA674ACF4781D51A9))
(waitingForDebugger)))
#<WAIT-GROUP :counter 2>
Sending: {"id":1,"sessionId":"A1BD02811FD42011A5325723F2D31819","method":"Runtime.evaluate","params":{"expression":"chrome.runtime.reload()"}}
Response: (OBJ (id . 2)
(result OBJ (sessionId . A1BD02811FD42011A5325723F2D31819)))
#<WAIT-GROUP :counter 2>
Sending: {"id":2,"sessionId":"A1BD02811FD42011A5325723F2D31819","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}}
Response: (OBJ (method . Target.attachedToTarget)
(params OBJ (sessionId . 4DC48E49A8133A13BED664D9C466F892)
(targetInfo OBJ (targetId . E1DA65BA7761486BBA9B341E5403744F)
(type . background_page)
(title . TITLE)
(url
. chrome-extension://EXTENSION_ID/_generated_background_page.html)
(attached . T) (canAccessOpener)
(browserContextId . 29837CF1E6AC13B4FDA7DD2883E6320E))
(waitingForDebugger)))
#<WAIT-GROUP :counter 2>
Sending: {"id":3,"sessionId":"4DC48E49A8133A13BED664D9C466F892","method":"Runtime.evaluate","params":{"expression":"chrome.runtime.reload()"}}
Response: (OBJ (id . 3)
(result OBJ (sessionId . 4DC48E49A8133A13BED664D9C466F892)))
#<WAIT-GROUP :counter 2>
Sending: {"id":4,"sessionId":"4DC48E49A8133A13BED664D9C466F892","method":"Runtime.evaluate","params":{"expression":"chrome.tabs.reload()"}}
Response: (OBJ (id . 1) (result OBJ (result OBJ (type . undefined)))
(sessionId . A1BD02811FD42011A5325723F2D31819))
#<WAIT-GROUP :counter 2>
Response: (OBJ (id . 2) (result OBJ (result OBJ (type . undefined)))
(sessionId . A1BD02811FD42011A5325723F2D31819))
#<WAIT-GROUP :counter 1>
Response: (OBJ (id . 3) (result OBJ (result OBJ (type . undefined)))
(sessionId . 4DC48E49A8133A13BED664D9C466F892))
#<WAIT-GROUP :counter 0>
Response: (OBJ (id . 4) (result OBJ (result OBJ (type . undefined)))
(sessionId . 4DC48E49A8133A13BED664D9C466F892))
#<WAIT-GROUP :counter -1>
|
|
Realised I'm only printing the received messages. It would help to see
what messages we send and when too. Still having the inconsistent tab
reload problem, so it looks like my
16c8122254725805be666cf065c590d54d66dfad change didn't fix it.
|
|
Let's keep a way to print WebSocket messages for debugging purposes in
the release build rather than remove the messages completely. Since I've
been struggling with the messages so much it seems like this could be a
useful thing to have.
|
|
|
|
Looks like this was the answer to the problem of the active tab not
reloading consistently.
Previously, if I had two instances of an extension loaded in two
separate Chrome profiles, the following could happen:
1. Neither profile's active tab reloaded
2. Only one profile's active tab reloaded
3. Both profiles' active tabs reloaded
With this change, both profiles' active tabs reload correctly and
consistently.
|
|
Move the response print calls to the top of the WebSocket message
receiver to make debug output chronology easier to follow.
|
|
The default executable compiled by SBCL is huge. Copied code from:
https://lispcookbook.github.io/cl-cookbook/scripting.html#building-a-smaller-binary-with-sbcls-core-compression
to produce a smaller executable.
Here's the size comparison:
$ du -hs extreload*
11M extreload-ecl
58M extreload-sbcl
15M extreload-sbcl-compressed
|
|
Wanted to try using ECL to build a smaller executable.
The commented section is adapted from the SBCL build command in the
`build` target. Didn't work, the build errored with the following:
An error occurred during initialization:
Unable to create pipe
C library explanation: Too many open files..
ext::getcwd error: Too many open files
Internal or unrecoverable error in:
Can't work without CWD
[24: Too many open files]
The second build command comes from:
https://gitlab.com/embeddable-common-lisp/ecl/-/tree/6a5dea52/examples/asdf_with_dependence
That one compiled without errors, but resulted in the following runtime
error:
$ ./extreload
Condition of type: SIMPLE-ERROR
The packages
((UIOP/OS . #<UIOP/OS package>) (UIOP/PATHNAME . #<UIOP/PATHNAME package>))
were referenced in compiled file
NIL
but have not been created
Available restarts:
1. (IGNORE) Ignore the error, and try the operation again
Top level in: #<process TOP-LEVEL 0x1045acf80>.
|
|
|
|
That function was originally intended to be doing reloading, but that
didn't turn out to be the case. In order to do the reloading, we first
need to attach to the extensions individually. Rename the function to
better correspond to what it does.
|
|
Don't need this now that we have a `make-config` constructor.
|
|
|
|
Set a five second timeout to ensure we don't block endlessly if we send
a WebSocket message and don't receive a response in a reasonable amount
of time.
Chose five seconds arbitrarily, but that seems like more than enough
time to do our work. If it takes longer, something else is probably
wrong.
|
|
|
|
|
|
|
|
|
|
I wanted to centralise the formatting of error printing.
|
|
|
|
|
|
A bit crude, but it covers us when extensions are in multiple Chrome
profiles. This ensures the desired tab is reloaded because all current
tabs in all profiles that have requested extensions are reloaded.
Not very intelligent, but a simple approach.
|
|
Didn't reload the active tab in my test. But the previous way doesn't
work when multiple copies of the same extension appear in the list of
targets.
Think we might want to always reload the current tab after reloading an
extension because the extension targets could be in different Chrome
profiles. Thus, you couldn't be sure which tab would be reloaded.
|
|
If we reload the active tab and it fails, we'll get an error response
back. Keep trying to reload the page until we no longer get the error.
|
|
Tried using manually-incremented `*reloaded-count*` but that didn't
quite work as I didn't have the right conditions to start the reload.
Then tried setting up the condition such that we reload when the
response comes back from the extension reload message. We can tell this
when we get a `result` response that includes a `sessionId` field. To
execute the reload a single time, store the most recent session ID, and
compare against that.
Using conditions on both the reloaded count (which needs to be changed
to handle multiple copies of the same extension) and the last session ID
in the message contents, we have enough to set up the reload in the tab.
Added the `sleep` call back in because otherwise I got this error:
reloading NOW
Response: (OBJ (id . 2)
(result OBJ (sessionId . 106D182E44C641B22EC65E9F6458B245)))
#<WAIT-GROUP :counter 2>
Response: (OBJ (id . 1)
(result OBJ
(result OBJ (type . object) (subtype . error)
(className . TypeError)
(description
. TypeError: Cannot read property 'reload' of undefined
at <anonymous>:1:16)
(objectId . 8548451452974044825.19.1))
(exceptionDetails OBJ (exceptionId . 2) (text . Uncaught)
(lineNumber . 0) (columnNumber . 15) (scriptId . 147)
(exception OBJ (type . object) (subtype . error)
(className . TypeError)
(description
. TypeError: Cannot read property 'reload' of undefined
at <anonymous>:1:16)
(objectId . 8548451452974044825.19.2))))
(sessionId . 106D182E44C641B22EC65E9F6458B245))
#<WAIT-GROUP :counter 1>
Response: (OBJ (id . 2)
(result OBJ
(result OBJ (type . object) (subtype . error)
(className . TypeError)
(description
. TypeError: Cannot read property 'reload' of undefined
at <anonymous>:1:13)
(objectId . 8548451452974044825.19.3))
(exceptionDetails OBJ (exceptionId . 3) (text . Uncaught)
(lineNumber . 0) (columnNumber . 12) (scriptId . 156)
(exception OBJ (type . object) (subtype . error)
(className . TypeError)
(description
. TypeError: Cannot read property 'reload' of undefined
at <anonymous>:1:13)
(objectId . 8548451452974044825.19.4))))
(sessionId . 106D182E44C641B22EC65E9F6458B245))
That tells us that the tab reload message was sent to the extension's
background page before it had a chance to fully reload. We thus need to
wait until the extension is fully reloaded before being able to send the
tab reload message.
Don't like the sleep call here. Would be nice to have a more robust
solution that didn't wait an arbitrary amount of time. Maybe we can keep
sending the tab reload message until we get a response that's not an
error.
|
|
Trying to set up the reload on the active tab after all extensions are
reloaded. It's only working half the time and I can't figure out what
I'm doing wrong. Something wrong with the wait group I think.
Committing what I have and might try other ideas.
|
|
|
|
|
|
|
|
Previously, we'd drop into the debugger on uncaught errors. Instead, we
should just exit with an error message.
|
|
|
|
Remove the hard-coded call IDs and replace them with a class that keeps
track of the current call ID and allows for easy incrementing to get the
next ID.
This should allow us to give multiple extension IDs on the command line
and send messages with properly incrementing call IDs.
Didn't touch the `runtime-evaluate-msg` message call ID because that one
is local to the target it's attached to, so we can keep it at ID "1".
|
|
|
|
|
|
Reload the extension IDs given on the command line now that we have them
from the `config` object. Replace the hard-coded extension ID that I had
been using for testing.
|