Pinned Post

Who picks the tool

Bild
The previous post ended with an agent that writes a missing tool into a running node. Generate, sanitize, persist, compile, load, execute, about 25 milliseconds after the model answers. I was happy with that for roughly a week. Then I looked at the demo page again and counted the text fields. Tool name. What it should do. Parameters as JSON. I had filled in all three. The gap-finding was real. The deciding was mine. MetaPlannerAgent.run("Publish the article", [ %{tool: "classic_plan", params: %{goal: "Write draft, review, publish"}}, %{tool: "slugify_text", description: "Turns a title into a URL slug", params: %{text: "Hello World"}} ]) Everything interesting in that call sits in the second argument, and I typed it. The agent resolved slugify_text , noticed it wasn't in the catalog and had it written. It never asked whether the task needed a slug at all. So this post is about the agent in front of that, the on...

Verteiltes Erlang

Systemarchitektur




















- IMac mit OSX
- PS3 mit Yellow Dog Linux 6.2
- Erlang


Vorbereitungen


Die PS3 und der IMac müssen sich kennen. Das kann man sehr einfach mit einem ping Rechnernamen überprüfen. Sollte das nicht funktionieren, so fügt man die IP Addresse und den Hostnamen der jeweiligen /etc/hosts hinzu. Also, in die /etc/hosts des IMac fügt man die IP Addresse und den Hostnamen der PS3 hinzu und umgekehrt.

Bespiel IMac:

    192.168.2.34    ps3.localdomain.de

Auf der PS3 und dem IMac muß Erlang installiert sein.

Node Namen

Damit wir eine Verbindung zwischen den beiden Erlang Instanzen herzustellen, starten wir die Erlang Nodes mit dem Parameter name (Langname des Rechners. Hier z.B. ps3.localdomain.de)

    erl -name ps3.localdomain.de

Den Namen der Node kann man in der Shell mit

    node().

abfragen.
Möchte man alle Nodes ermitteln, die mit einer Node verbunden sind, so kann man das mittels

   nodes().

machen.

Damit die Laufzeit weiß, welche Rechner sie ansprechen kann, erzeugen wir die Datei $HOME/.hosts.erlang , in der wir die Rechnername eintragen. Um den richtigen Rechnernamen zu ermitteln, benutze ich das unix Kommando hostname.

    'Ulfs-IMac-3.local'.
  'ps3.localdomain.de'.

Anmerkung: Konfigurationen sind im Normalfall Erlang Terme. In diesem Beispiel sind es zwe atoms die per file:path_consult eingelesen werden und dann direkt als Liste von atoms zur Verfügung stehen.

Auch hier gibt es wieder eine Möglichkeit zu überprüfen, ob die Datei auch richtig plaziert wurde

    net_adm:host_file().

Cookies


Um nur die Nodes miteinander zu verbinden, die auch für einander bestimmt sind, gibt es den Konstrukt Cookie. Es verbinden sich nur Nodes miteinander, die den gleichen Cookie haben.

    erl -name ps3.localdomain.de -setcookie secure

Alternativ kann man den Cookie auch in der Datei $HOME/.erlang.cookie eintragen.

    secure

oder aber in der Shell oder einem Programm via

    erlang:set_cookie(node(), 'secure').

setzen.

Ob ein Cookie gesetzt ist kann man mit

    erlang:get_cookie().

abfragen.

Auf geht's


Nachdem wir die Vorbereitungen abgeschlossen haben und die Nodes auf dem IMac und der PS3 gestartet haben, können wir schaun ob unsere Bemühungen gefruchtet haben.

    net_adm:world().

liest die .host.erlang aus und setzt einen ping an die jeweiligen Nodes ab.


Verteilte Mnesia DB


Wir haben nun eine laufende Erlang Node auf der PS3 und dem IMac. Das war die Voraussetzung für unser weiteren Unternehmungen. Zunächst werde ich alle erforderlichen Schritte manuell durchführen, damit wir uns jeden einzelnen Befehl anschaun können.

Wir müssen am Anfang überprüfen, ob Mnesia noch läuft. Sollte das der Fall sein, so müssen wir die DB stoppen.
Mit

    mnesia:info().

kann man sich den Status ausgeben lassen. Sollte Mnesia noch laufen, so kann die Instanz mit

    mnesia:stop().

auf den jeweiligen Nodes gestoppt werden. Später werde ich zeigen, wie man von einer Node alle Mnesia Instanzen stoppen kann.


Mit der Funktion mnesia createSchema  wird auf den angegeben Nodes lokal die neue DB erzeugt.

   mnesia:create_schema([node(), 'ps3.localdomain.de']).

wobei node()den Namen der aktuellen Node zurück gibt. 

Nun muß man auf den einzelnen Nodes Mnesia starten.
 

   mnesia:start().

und kann nun die benötigten Tabellen erzeugen. Die Funktion zum Erzeugen der Tabellen wird wieder nur auf einer Node durchgeführt und den Rest übernimmt Mnesia.

mnesia:create_table(user,[{disc_copies, [node(), 'ps3@localdomain.de']}, {attributes, record_info(fields, user)}]).

In diesem Beispiel wird die Tabelle user als disc_copies angelegt. Das bedeutet, dass alle schreibenden Operationen auf die Festplatte und in den Speicher geschrieben werden.
Die darauf folgende Liste gibt an, auf welchen Nodes diese Tabelle angelegt werden soll und das abschließende Tuple gibt an, welche Attribute die Tabelle user hat.

Um seine Installation zu testen, kann man nun auf einer Node einen neuen Satz in die Datenbank einfügen und auf der anderen Node überprüfen, ob dieser Satz auch auf dieser Node zur Verfügung steht. Zur Überprüfung kann man entweder in der Shell eine Abfrage starten, oder aber das Tool

Kommentare

Beliebte Posts aus diesem Blog

Splitting an ML model and a web app across two BEAM nodes — the technical blueprint

Jido in Practice: Agents in Elixir as Composable Actions

A Foundation Model in the BEAM: On-Chain Anomalies with Google TimesFM in Elixir