pmargreff

pmargreff

Send StringIO to Stream

I have a process where I’m creating and accumulating a string into a StringIO file, the creation and aggregation, it is simple, I open the string IO and send the PID with process state.

# process init    
{:ok, pid} = StringIO.open("stream_buffer")
# call proccess to aggregation 
IO.write(pid, text <> " ")

The problem is, when I’m finishing the process, I want to send it directly to a stream. I use to save it to a file, but when the buffer is too big (1 or 2 GBs), the process to send it to a file and get it back takes more time than I wish to wait.

My first try to send it directly into a stream was something like this:

    pid
    |> IO.binstream(:line)

The problem with this try (and I don’t understand if it is intentional or not) is that this instead of getting the content written on this IO returns the content I’ve used on open. So instead of transform, my content aggregated trough IO.write it always transforms the content I’ve used as the “stream name”, example:

{:ok, pid} = StringIO.open("buffer")
IO.write(pid, "And here we should have the buffer content")

# will evaluate to {"buffer", "And here we should have the buffer content"}
pid
|> StringIO.describe()
|> IO.inspect()

# will evaluate "buffer", but I expect it evaluate the whole buffer content, not only the initial value
pid
|> IO.binstream(:line)
|> Stream.map(&IO.inspect/1)
|> Stream.run()

What I’m doing now, it’s creating a new StringIO with the old one content, what I’m feeling it’s really wrong:

{:ok, other_pid} = pid
|> StringIO.flush()
|> StringIO.open() 

So I yank the content from the PID where I was aggregating to a new device, the problem is:
1 - It really feels wrong.
2 - When the String is huge this yank operation from the old to the new device still takin a lot of time (lass than create and read a file from disk, but still slow)

What I’m doing wrong here? What are the other options to process it on the fly using streams, are other possible options besides StringIO?

Marked As Solved

akash-akya

akash-akya

I think there is a confusion here, StringIO is not really a buffer in the way you are trying to use.

Maybe this example might help.
Think of it like a terminal and you are running a program inside this terminal. so your program gets its input from the terminal and write its output to terminal. All IO functionality are there from the perspective of this program. That means Enumeration is pulling the input from the terminal (you can not pull output in this context). And you push your output to the terminal, that is Collectable.

For example:

defmodule Capitalize do
  def run(terminal) do
    stream = IO.binstream(terminal, :line)

    stream
    |> Stream.map(&String.capitalize/1) # we are pulling `input` here
    |> Stream.into(stream)
    |> Stream.run()
  end
end

input = ["a", "b", "c", "d"] |> Enum.join("\n")
{:ok, terminal} = StringIO.open(input)

Capitalize.run(terminal)

{"", output} = StringIO.contents(terminal)
# "A\nB\nC\nD"

Also StringIO might not be efficient in the way you are using. With the quick glance its just concatenating the output https://github.com/elixir-lang/elixir/blob/v1.10.3/lib/elixir/lib/string_io.ex#L287. You are better of using iodata

Where Next?

Popular in Questions Top

yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
jc00ke
Expanding on this topic: https://forum.elixirforum.net/t/map-typespec-question/19217 Let’s say I have a map with required and optional k...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

We're in Beta

About us Mission Statement