diff options
Diffstat (limited to 'blog/content/notes/tech')
5 files changed, 76 insertions, 10 deletions
diff --git a/blog/content/notes/tech/about-relational-databases.gmi b/blog/content/notes/tech/about-relational-databases.gmi index c66a530f..d08071ac 100644 --- a/blog/content/notes/tech/about-relational-databases.gmi +++ b/blog/content/notes/tech/about-relational-databases.gmi @@ -21,7 +21,7 @@ Many computer languages have similar concepts: * C++ std::map * Java java.util.Map * C# System.Collections.Generic.Dictionary -* Javascript Object +* JavaScript Object * PHP arrays Relations are a natural concept, so although non-relational data systems exist, most data can be stored as relations. diff --git a/blog/content/notes/tech/about-web-development.gmi b/blog/content/notes/tech/about-web-development.gmi new file mode 100644 index 00000000..bcc54cb8 --- /dev/null +++ b/blog/content/notes/tech/about-web-development.gmi @@ -0,0 +1,5 @@ +# About web development + +* Ensure that the website is as functional as possible using limited browsers such as Lynx, ELinks, w3m, or Dillo. (If you use a browser that can display images, ensure that the website is as functional as possible with images disabled too.) +* Make sure all content in the website has a URL that can be shared conveniently. +* If website users would benefit from learning about updates to your website, then provide well-visible open ways to follow updates, such as RSS/Atom feeds, email subscriptions, or ActivityPub feeds. diff --git a/blog/content/notes/tech/gadgets/pocket-computers.gmi b/blog/content/notes/tech/gadgets/pocket-computers.gmi index a31970ef..e2cd7a2f 100644 --- a/blog/content/notes/tech/gadgets/pocket-computers.gmi +++ b/blog/content/notes/tech/gadgets/pocket-computers.gmi @@ -8,16 +8,8 @@ The Blackberry KeyONE I used 2017-2021 was the last device I used that had this Since then, I believe the loss of physical keyboard phones means that some uses of the smartphone have disappeared. -=> https://www.bringbackblackberry.com/ - ## Current devices -=> https://www.unihertz.com/products/titan-pocket Titan Pocket (owned) - -* The keyboard feels worse than a Blackberry -* The keyboard has deteriorated with age (some keys require extra pressure to activate, meaning typing is painful) -* The keyboard software is insufficient for writing in Spanish and Catalan - => https://www.clicksphone.com/communicator Clicks Communicator => https://www.clicksphone.com/powerkeyboard Clicks Power Keyboard => https://keyphone.tech Keyphone @@ -29,6 +21,14 @@ Since then, I believe the loss of physical keyboard phones means that some uses => https://www.tindie.com/stores/zitaotech ZitaoTech refurbs keyboards, but they seem to be permanently out of stock. => https://linkapus.com/ The Q25 project is a project to put an Android phone inside a Blackberry Classic shell. +## Recent devices + +=> https://www.unihertz.com/products/titan-pocket Titan Pocket (owned) + +* The keyboard feels worse than a Blackberry and deteriorates with age (some keys require extra pressure to activate, meaning typing is painful) +* The keyboard software is insufficient for writing in Spanish and Catalan +* My battery swelled and I retired it + ## Obstacles ### Communication platforms without an open API diff --git a/blog/content/notes/tech/misc-python-stuff.gmi b/blog/content/notes/tech/misc-python-stuff.gmi index 6672e021..f7cc33e7 100644 --- a/blog/content/notes/tech/misc-python-stuff.gmi +++ b/blog/content/notes/tech/misc-python-stuff.gmi @@ -39,7 +39,7 @@ The standard library still includes a lot of batteries: * textwrap.dedent and str.[lr]strip for embedding multiline strings in code. * urllib.request is clunkier than third-party libraries, but it's usable. -(Also for very simple stuff, tkinter can implement simple graphical tools.) +For very simple stuff, tkinter can implement simple graphical tools and wsgiref can implement simple web apps (that you can even deploy with CGI). ### Subprocess diff --git a/blog/content/notes/tech/motivating-example-for-logical-replication-for-dynamic-ui.gmi b/blog/content/notes/tech/motivating-example-for-logical-replication-for-dynamic-ui.gmi new file mode 100644 index 00000000..01fc5fae --- /dev/null +++ b/blog/content/notes/tech/motivating-example-for-logical-replication-for-dynamic-ui.gmi @@ -0,0 +1,61 @@ +# Motivating example for logical replication with dynamic UI + +(I'm almost sure what I write below is a horrible idea that will melt a PostgreSQL server with very few "real-time queries" at the same time. I'm very curious about how much load could PostgreSQL handle efficiently using this schema.) + +Suppose the following database schema (pseudo-SQL): + +```sql +create table chat_messages ( + id serial primary key, + posted timestamp not null, + channel text not null references chats(id), + author text not null references users(id), + message text not null +); +``` + +Imagine you could write an UI element that subscribed to the following publication: + +``` +create publication foo for table chat_messages where (channel in :list_of_channels_user_is_in and posted > :some_time_ago); +``` + +Without writing any additional code, the UI element would get instantly notified not only of all new messages, but also of editions, deletions, or messages moved in or out of the subscribed channels. I believe you could write a real-time UI element with much shorter and safer code than any alternative I can think of that only uses OSS code. (As far as I know, ksqlDB does a similar thing, but has non-OSS bits and seems much harder to deploy than PostgreSQL, besides you would also need to deploy PostgreSQL.) + +This has some caveats: + +* Publications cannot do "joins", and implementing any live UI element that requires joins would be much more complex. (And I'm not sure it would still be the best way to implement things.) +* This likely cannot be implemented efficiently without having all working set data in RAM (e.g. all the data involved in all subscriptions). + +My idea is writing: + +* A daemon that provides an API that can be used as in the following example: + +``` +subscription = subscribe("chat_messages", column("channel").in(list_of_channels) and column("posted").gt(some_time_ago)) +while update = subscription.next(): + for chat_message in sorted(update.all_current_results(), key=lambda chat_message: chat_message.posted): + print(chat_message.current_values, chat_messages.previous_values) + print(update.deleted_since_last_update_results()) +``` + +* Libraries for stacks such as "Django + HTMX", "GTK", etc. that allow to build UI elements that use the daemon API underneath, so you could write things like: + +``` +<ul class="channels"> + {% foreach channel in joined_channels %} + <li> + {{ channel.name }} + last message: {{ for chat_message in update_all_current_results() if chat_message.current_values.channel == channel | max(lambda chat_message: chat_message.current_values.posted) }} + </li> + {% end foreach %} +</ul> + +<ul class="current_chat_messages"> + {% foreach chat_message in update.all_current_results() if chat_message.current_values.channel == current_channel %} + <li>{{ chat_message.current_values.author }} {{ chat_message.current_values.message }}</li> + {% end foreach %} +</ul> +``` + +For stacks such as Django/HTMX, in simpler websites you could have websites that degrade gracefully out of the box without JS, just losing real-time updates. |
