Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REPL: fix the process of reading data from the server. #421

Merged
merged 12 commits into from
Apr 26, 2023
Merged

REPL: fix the process of reading data from the server. #421

merged 12 commits into from
Apr 26, 2023

Conversation

Hanaasagi
Copy link
Contributor

Fixes the bug introduced by #420

This is a brief description.

  • Introduce a small data protocol, where the first two bytes represent the length of the data. So the client knows how many bytes to read.

Changes proposed in this PR:

@mtshiba

src/scripts/repl_server.py Outdated Show resolved Hide resolved
src/dummy.rs Outdated Show resolved Hide resolved
@mtshiba
Copy link
Member

mtshiba commented Apr 22, 2023

As you point out, the data format should be well-defined. We have defined the length section, but there is a confusion between instructions and data.

Here is a format, I just came up with.
This shall be a common protocol for both client (Erg DummyVM) and server (repl_server.py).

format ::= length ' [' instruction '] ' data
instruction ::= 'print' | 'load' | 'exit' | 'initialize' | 'exception' | 'unknown'
  • print: Send from server to client. Informs the client to print data.
  • load: Send from client to server. Informs the REPL server that the executable .pyc file has been written out and is ready for evaluation.
  • exception: Send from server to client. Represents an exception.
  • initialize: Send from server to client. Tells the code generator to initialize due to an error.
  • exit: Informs that the connection is to be / should be terminated.
  • unknown: Informs that it is not a supported instruction.

quit and closed are removed. data can be empty.

@Hanaasagi
Copy link
Contributor Author

Perhaps we should put the instruction section at the beginning, because some instructions, like load, are not followed by data.

-------------------------------
| ins    | size    | data 
-------------------------------
| 1 byte | 2 bytes | n bytes
-------------------------------

And the instruction can be represented directly in bytes, without the need for a format like [Exception].

enum Inst {
    Print = 0x01,
    Load = 0x02,
    // ...
}

@mtshiba
Copy link
Member

mtshiba commented Apr 22, 2023

That looks better :)

@Hanaasagi
Copy link
Contributor Author

Hanaasagi commented Apr 22, 2023 via email

src/scripts/repl_server.py Outdated Show resolved Hide resolved
@Hanaasagi Hanaasagi requested a review from mtshiba April 23, 2023 08:37
src/scripts/repl_server.py Outdated Show resolved Hide resolved
@Hanaasagi
Copy link
Contributor Author

A simple test for socket read and write.

import itertools
import random
import string

with open("./src/scripts/repl_server.py") as f:
    code = f.readlines()

code.insert(0, "__PORT__ = 9000\n")
code = itertools.takewhile(lambda l: not l.startswith("# DummyVM"), code)

exec("".join(code))


class MockSocket:
    def __init__(self):
        self.data = bytearray()
        self.cursor = 0

    def send(self, data):
        self.data.extend(data)

    def recv(self, _bufsize):
        if self.cursor >= len(self.data):
            raise Exception()
        # return one byte everytime
        data = bytes(self.data[self.cursor : self.cursor + 1])
        self.cursor += 1
        return data


corr_data = "".join(random.choices(string.ascii_uppercase + string.digits, k=2048))
s = MessageStream(MockSocket())
s.send_msg(INST.PRINT, corr_data)
inst, recv_data = s.recv_msg()

assert inst == INST.PRINT
assert recv_data == corr_data

@Hanaasagi Hanaasagi requested a review from mtshiba April 24, 2023 17:25
src/dummy.rs Outdated Show resolved Hide resolved
src/scripts/repl_server.py Outdated Show resolved Hide resolved
@mtshiba
Copy link
Member

mtshiba commented Apr 26, 2023

A simple test for socket read and write.

import itertools
import random
import string

...

I'll make a few edits and add this one to the test suite, ok?

@Hanaasagi
Copy link
Contributor Author

Sure, no problem. Thank you for your review and edits.

@mtshiba mtshiba merged commit 1d140bc into erg-lang:main Apr 26, 2023
@mtshiba
Copy link
Member

mtshiba commented Apr 26, 2023

Thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants