Hi dear @lud , I talked about this way I want to do in these post, I am open to receive any suggestion
Hi, imagine you want to add a new dep in your project without restart your app:
Code.prepend_path(path)
Application.load(timex)
Application.ensure_all_started(timex)
With these 3 functions and a new source which is compiled before, your project can use new deps. But I have a problem to update an installed-app like timex.
For example, I want to update timex to new version: if I call the Application.load(app) and Application.ensure_all_started(app) functions, I can see this error: this dep is …
and
Hi friends, I have created a simple code to install deps in runtime. You can see it in this video.
It can help my CMS to have an installer, like Joomla, WordPress! But losing the app state will be updated is my problem.
The question is when admin user want to update a library which has state (it has been installed and activated before), I need to stop and unload it, hence I am going to lose the dep state, it is my responsibility to save external developer dep, or I need to create structure t…
and
That’s not really true stated like that. All the capabilities are available if you look at hot code updates. Even in releases you can just copy paste modules into the console and they’re compiled and kept in memory until the vm stops. The BEAM was built to explicitly allow for not needing to shutdown the system while the underlying codebase is continuously updated.
But there’s a lot more to maintaining a working system than compiling and loading modules and those are the problematic pieces. Th…
in this video, you can see a simple demo
with these line I add a dep or delete it from my source
Hence, the Phoenix Pubsub library can be an excellent option to notice processes are subscribed to in the MishkaInstaller channel.
## The purpose of this section is divided into two categories as follows:
1. View in the terminal
2. Send Ported Output by Pubsub
> This module requires the `import_path` as a variable system, which is your project's path.
---
### Below you can see the graph of connecting this module to another module.
```
+--------------------------------------------------+
| |
| |
| MishkaInstaller.Installer.DepHandler +--------------------+
| | |
| | |
So, my user need to add his package into deps
function and I create this for him/her
version: String.t() | nil,
type: String.t() | nil,
url: String.t() | nil,
git_tag: String.t() | nil,
custom_command: String.t() | nil,
dependency_type: String.t() | nil,
dependencies: [map()]
}
@doc """
The `run/2` function is actually the function of the installer and assembler of all the modules that this module is connected to.
This function has two inputs that you can see in the examples below. The first input is an atom, which specifies how to install a
So all the plugins are called from a JSON file which is created from my database
for example
%MishkaInstaller.Installer.DepHandler{
app: "mishka_social",
version: "0.0.2 ",
type: "hex",
url: "https://hex.pm/packages/mishka_social",
git_tag: nil,
custom_command: nil,
dependency_type: "force_update",
update_server: nil,
dependencies: [
%{app: :phoenix, min: "1.6"},
%{app: :phoenix_live_view, max: "0.17.7", min: "0.17.7"},
%{app: :ueberauth, max: "0.17.7", min: "0.17.7"},
%{app: :ueberauth_github, min: "0.8.1"},
%{app: :ueberauth_google, min: "0.10.1"},
]
}
So the only problem exist here that is keeping state when a dep was installed before. So my library let users register an event; before compiling I send a name of app and some information, if an app needs to save something, it prevents to force_update
, if not it is going to be run the bottom function.
# If you have a Task in your project you can load it in a list like [{:task_one, "ecto.migrate"}], it should be a list
@spec deps(list()) :: list
def deps(custom_command \\ []) when is_list(custom_command) do
[{:get, "deps.get"}, {:compile, "deps.compile"}] ++ custom_command
|> Enum.map(fn {operation, command} ->
{stream, status} = System.cmd("mix", [command], into: IO.stream(), stderr_to_stdout: true)
%{operation: operation, output: stream, status: status}
end)
end
In this function, when the lib gets an answer, it sends a pubsu
to used admin dashboard
@spec push(map(), String.t() | atom()) :: map()
def push(app, status) do
GenServer.call(__MODULE__, {:push, app: app, status: status})
end
@doc false
@spec get(String.t()) :: map()
def get(app) do
GenServer.call(__MODULE__, {:get, app})
end
@spec get :: map()
def get() do
GenServer.call(__MODULE__, :get)
end
A simple dashboard I’m developing it: mishka_installer/lib/installer/live/dep_getter.ex at master · mishka-group/mishka_installer · GitHub after that I add it in my CMS: GitHub - mishka-group/mishka-cms: MishkaCms an open source and real time API base CMS Powered by Elixir and Phoenix
My solution for event