Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use asyncio to greatly improve performance #270

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1541e6d
remove integer conversion in version tuple
taooceros Aug 25, 2023
7300579
use async io to improve performance
taooceros Aug 25, 2023
df30d0c
update ci
taooceros Aug 25, 2023
8d8a77e
remove unused import
taooceros Aug 25, 2023
e399167
remove more
taooceros Aug 25, 2023
5d98583
change branch for testing
taooceros Aug 25, 2023
83ef633
use index to panic if key not exist
taooceros Aug 25, 2023
9801024
auto updated plugins
taooceros Aug 25, 2023
99c0769
for debugging
taooceros Aug 25, 2023
b6b70a3
Merge branch 'asyncio-revision' of https://github.com/Flow-Launcher/F…
taooceros Aug 25, 2023
071a391
remove personal token
taooceros Aug 25, 2023
ab86753
auto updated plugins
taooceros Aug 25, 2023
1cdd58c
test github token
taooceros Aug 26, 2023
03fa2bf
Merge branch 'asyncio-revision' of https://github.com/Flow-Launcher/F…
taooceros Aug 26, 2023
857e659
fix typo
taooceros Aug 26, 2023
ee0b93d
auto updated plugins
taooceros Aug 26, 2023
445ab72
fix not wawited post
taooceros Aug 26, 2023
e25c791
Merge branch 'asyncio-revision' of https://github.com/Flow-Launcher/F…
taooceros Aug 26, 2023
eb4db4b
use earlier plugin.json for testing
taooceros Aug 26, 2023
3fddf6b
auto updated plugins
taooceros Aug 26, 2023
504adc6
fix a potential bug for newly added plugin
taooceros Aug 26, 2023
874d739
Merge branch 'asyncio-revision' of https://github.com/Flow-Launcher/F…
taooceros Aug 26, 2023
fc9b31a
auto updated plugins
taooceros Aug 26, 2023
14587f0
revert the target branch to plugin_api_v2
taooceros Aug 26, 2023
2136069
Merge branch 'asyncio-revision' of https://github.com/Flow-Launcher/F…
taooceros Aug 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/updater.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
token: ${{ secrets.UPDATER }}
# otherwise, you will failed to push refs to dest repo
fetch-depth: 0

- uses: actions/setup-python@v2
- uses: actions/setup-python@v4
with:
python-version: "3.x"

Expand All @@ -32,4 +32,4 @@ jobs:
with:
commit_message: "auto updated plugins"
push_options: --force
branch: plugin_api_v2
branch: asyncio-revision
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be plugin_api_v2 instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes for testing purpose

2 changes: 1 addition & 1 deletion ci/envs/requirements-updater.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
requests
aiohttp
tqdm
2 changes: 1 addition & 1 deletion ci/src/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def clean(string: str, flag="-") -> str:

def version_tuple(version: str) -> tuple:
version = clean(version, "v")
return tuple(map(int, (version.split("."))))
return tuple(version.split("."))

def check_url(url: str) -> bool:
regex = re.compile(
Expand Down
8 changes: 5 additions & 3 deletions ci/src/discord.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import requests
import aiohttp

from _utils import *

MAX_BODY_LEN = 1024


def update_hook(webhook_url: str, info: dict, latest_ver: str, release: dict) -> None:
async def update_hook(webhook_url: str, info: dict, latest_ver: str, release: dict) -> None:
embed = {
"content": None,
"embeds": [
Expand Down Expand Up @@ -41,7 +41,9 @@ def update_hook(webhook_url: str, info: dict, latest_ver: str, release: dict) ->
release_notes = release.get('body')
if release_notes and release_notes.strip():
embed['embeds'][0]['fields'].append({"name": "Release Notes", "value": truncate_release_notes(release['html_url'], release.get('body', ""))})
requests.post(webhook_url, json=embed)

async with aiohttp.ClientSession() as session:
session.post(webhook_url, json=embed)

def truncate_release_notes(url: str, release_notes: str, length: int = MAX_BODY_LEN) -> str:
if len(release_notes) <= length:
Expand Down
104 changes: 65 additions & 39 deletions ci/src/updater.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
# -*-coding: utf-8 -*-
from http.client import responses
import asyncio
from typing import List
from unicodedata import name
from sys import argv
import traceback
import aiohttp

import requests
from tqdm import tqdm
from tqdm.asyncio import tqdm

from _utils import *
from discord import update_hook


def batch_github_plugin_info(info: P, tags: ETagsType, webhook_url: str = None) -> P:
async def batch_github_plugin_info(
info: P, tags: ETagsType, webhook_url: str = None
) -> P:
try:
headers = None
if "github.com" not in info[url_download]:
Expand All @@ -26,70 +28,94 @@ def batch_github_plugin_info(info: P, tags: ETagsType, webhook_url: str = None)
tag: str = tags.get(info[id_name], info.get(etag, ""))

if release_date in info.keys():
headers = {"If-None-Match": tag}
res = requests.get(
url_release.format(repo=repo),
headers=headers,
)
if res.status_code in (403, 304):
return info

latest_rel = res.json()
assets = latest_rel.get("assets")
if info.get(release_date, '') != latest_rel.get('published_at'):
info[release_date] = latest_rel.get('published_at')
if assets:
info[url_download] = assets[0]["browser_download_url"]
send_notification(info, clean(
latest_rel["tag_name"], "v"), latest_rel, webhook_url)
info[version] = clean(latest_rel["tag_name"], "v")

tags[info[id_name]] = res.headers.get(etag, "")

return info
headers = {
"If-None-Match": tag
}

async with aiohttp.ClientSession() as session:
async with session.get(
url_release.format(repo=repo),
headers=headers,
) as res:
if res.status in (403, 304):
return info

latest_rel = await res.json()

assets = latest_rel.get("assets")

tqdm.write(str(latest_rel))

if info.get(release_date, "") != latest_rel["published_at"]:
info[release_date] = latest_rel.get("published_at")
if assets:
info[url_download] = assets[0]["browser_download_url"]
await send_notification(
info,
clean(latest_rel["tag_name"], "v"),
latest_rel,
webhook_url,
)
info[version] = clean(latest_rel["tag_name"], "v")

tags[info[id_name]] = res.headers.get(etag, "")

return info
except Exception as e:
tb = traceback.format_exc()
print(f"Error when processing plugin {info[plugin_name]}:\n{e} {tb}")
return info


def batch_plugin_infos(plugin_infos: Ps, tags: ETagsType, webhook_url: str = None) -> Ps:
return [batch_github_plugin_info(info, tags, webhook_url) for info in tqdm(plugin_infos)]
async def batch_plugin_infos(
plugin_infos: Ps, tags: ETagsType, webhook_url: str = None
) -> Ps:
return await tqdm.gather(
*[
batch_github_plugin_info(info, tags, webhook_url)
for info in tqdm(plugin_infos)
]
)


def remove_unused_etags(plugin_infos: Ps, etags: ETagsType) -> ETagsType:
etags_updated = {}
plugin_ids = [info.get("ID") for info in plugin_infos]

for id, tag in etags.items():

if id not in plugin_ids:
print(f"Plugin with ID {id} has been removed. The associated ETag will be also removed now.")
print(
f"Plugin with ID {id} has been removed. The associated ETag will be also removed now."
)
continue

etags_updated[id] = tag

return etags_updated


def send_notification(info: P, latest_ver, release, webhook_url: str = None) -> None:
async def send_notification(info: P, latest_ver, release, webhook_url: str = None) -> None:
if version_tuple(info[version]) != version_tuple(latest_ver):
tqdm.write(f"Update detected: {info[plugin_name]} {latest_ver}")
try:
update_hook(webhook_url, info, latest_ver, release)
await update_hook(webhook_url, info, latest_ver, release)
except Exception as e:
tqdm.write(e)
tqdm.write(str(e))


if __name__ == "__main__":
async def main():
webhook_url = None
if len(argv) > 1:
webhook_url = argv[1]
plugin_infos = plugin_reader()
etags = etag_reader()
plugin_infos_new = batch_plugin_infos(plugin_infos, etags, webhook_url)

plugin_infos_new = await batch_plugin_infos(plugin_infos, etags, webhook_url)
plugin_writer(plugin_infos_new)

etags_new = remove_unused_etags(plugin_infos_new, etags)
etags_writer(etags_new)


if __name__ == "__main__":
asyncio.run(main())
Loading