Rich_Morin

Rich_Morin

I’m interested in building a personal web server to aid accessibility. I’ve figured out much of the basic architecture, using Broadway and LiveView, but many details are still murky. So, suggestions are most welcome!

Details

I’m interested in building a personal web server to aid accessibility. It should act as an information portal, making both local files and web resources more accessible. For example, it might:

  • present external web pages in an extended form

    • maintain original appearance and behavior by default
    • command keys bring up navigable dialogs of extensions
    • common accessibility problems can be remedied
    • content (e.g., index, summaries) can be added
  • convert data files and documents to accessible formats

    • structured HTML is the default output format for text
    • other formats include braille displays, stereo audio, etc.
  • perform recognition and transformation on images, etc.

    • characterize and classify images
    • turn presentation slides and videos into HTML
    • sonify pictorial images (e.g., via the vOICe)

The basis for this would be a Phoenix app, taking advantage of Broadway and LiveView. Broadway would oversee data transformations; LiveView would add behavior to web pages.

Basically, the server is acting as an intelligent web cache. So, it needs to faithfully reproduce the appearance and behavior of the web pages being presented. I’m not at all sure what sorts of things a site might do, so this part is rather scary. I’d love to find an example to start from!

Data transformation is another interesting part of the design. Broadway handles a number of thorny issues (thanks!), but its fundamental API is based on making function calls. In order to dynamically create DAGs of actors, I’d like to build up graph descriptions as data structures, then send them off to a Broadway-based interpreter for execution. The exact data structure and preferred serialization format are still up for grabs.

There’s plenty more that we could discuss, but this should get things started… (ducks)

-r

Showing Posts 1 to 4

MrDoops

MrDoops

Using a DAG for describing the dependencies between jobs to run in a Broadway pipeline is the direction I went as well. My use case was to modify a Natural Language Processing pipeline at run-time, but I think the approach is pretty flexible for other contexts.

The gist of the feature was a Dynamically Supervised GenServer maintains the NLP Job/DAGs and dispatches or modifies them when necessary. The WIP of the DAG can be found here. There’s also ETS for a job queue and caching that isn’t ready for multi-node, but it’s worth a look.

I was really happy that all the Broadway pipeline had to do was this:

@impl true
def handle_message(_processor, %Message{} = message, _context) do
  {:ok, ran_job} = Job.run(message.data)
  %Message{message | data: ran_job}
end

I’m planning on pulling this Job module and some supporting contracts into a library, but for now I need to get a feel for the use cases.

Right now the default behavior is to enqueue dependent jobs with the parent as the input upon success, but there are optimizations that a Broadway Processor could do to minimize latency, distribute work, and prevent unnecessary enqueuing, but it works well enough.

I really enjoyed working with Broadway for this project, so I’d love to see where you go with these accessibility use cases.

Rich_Morin

Rich_Morin OP

That looks like a great starting point. I’ll see if I can get a prototype working, based on your code. One thing I’m curious about is the repetition of the map keys as values for the name field, eg google_nlp in:

  google_nlp: %Job{
    name: :google_nlp,
    work: &GoogleNLP.analyze_text/1,
  },

It looks like this builds trees automagically, based on the hierarchy of the data structure, but I’m unclear about how a generalized DAG structure would be specified. Help?

-r

MrDoops

MrDoops

The main reasoning behind using the names as keys is so the code to modify the job pipeline at run-time is easier to write. Just some Map.get calls. The names as keys also helps with preventing duplicate jobs in the same level. I expect there would be a better way maybe by adding more info in the key to aid in retrieval.

The building of the pipeline is done here and dispatching the jobs here. The SessionProcess is just initiated with an empty map it uses to put the top-level jobs in. Each Job has a dependent job to publish to the PubSub currently, but it can be used for about as much arbitrary nesting as you can fit in-memory. Considering I ended up building helper functions to construct the pipeline I expect there’s a better abstraction hiding somewhere.

The gist is using Job.new/1 to build the struct with initial details and Job.add_dependent_job/2 to add something that should run after with the result of the parent. The purpose of the module is to describe the procedure that should take place for running the jobs. I.e. “Run this only after this, but this other thing can run concurrently if you want”.

Rich_Morin

Rich_Morin OP

Nobody has responded to the question about creating a server that can act as an intelligent web cache. Put another way, it needs to be a man-in-the-middle SSL proxy. Can anyone point me to existing work (preferably in Elixir or Ruby) on this sort of thing?

-r

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews