#JShell project for Tj-Bot!

1 messages · Page 5 of 1

bright lark
#

But dnt stop, this isn't guarantee

sterile crest
#

That's okay, I don't think we can figure this out with your knowledge and expertise so there's always the day after

#

Counting on you

ebon river
#

And what errors?

timber mirage
#

@sterile crest I'm here

sterile crest
#

hey ala

#

have you pushed your changes to a branch or main?

timber mirage
#

no

timber mirage
#

@ebon river try this branch and you will see

#

run a one time session

sterile crest
#

have you pushed the branch?

timber mirage
#

yes

sterile crest
#

1 min ago nice

timber mirage
sterile crest
#

send me the cURL command too you were testing with

timber mirage
ebon river
#

And what is weird there?

sterile crest
#

why am i not getting the errors @timber mirage ?

timber mirage
#

what

#

how

ebon river
#

I don't get any error either

timber mirage
#

-_-

#

this doesn't make any sense

sterile crest
#

what version of docker are you using?

ebon river
#

What version of the image are you using?

sterile crest
#

I'm on Docker version 26.1.1, build 4cf5afa

timber mirage
#

v24.0.2

sterile crest
#

I pulled the repo fresh and had a clean docker with no images or containers

ebon river
#
REPOSITORY                                         TAG       IMAGE ID       CREATED         SIZE
togetherjava.org:5001/togetherjava/jshellwrapper   master    1dddb68cf79d   2 minutes ago   343MB

I just built this from source

#

Docker version 27.1.1, build 63125853e3

timber mirage
#

it didn't change since a long time ago

ebon river
#

What is your exception?

sterile crest
#

once he calls close the container is killed but the underlying docker thread is still open and tries to read from stdin causing it to throw an IOException with some communication link as the error message

timber mirage
#

#

note that it even happens when the container closes itself gracefully

ebon river
#

I am not sure I follow

#

Can I get a stacktrace?

#

And what docker thread?

timber mirage
#

wait 30s please

sterile crest
#

the SDK creates a thread under the hood, at least for:

#
    public InputStream startAndAttachToContainer(String containerId, InputStream stdin)
            throws IOException {
        PipedInputStream pipeIn = new PipedInputStream();
        PipedOutputStream pipeOut = new PipedOutputStream(pipeIn);

        client.attachContainerCmd(containerId)
            .withLogs(true)
            .withFollowStream(true)
            .withStdOut(true)
            .withStdErr(true)
            .withStdIn(stdin)
            .exec(new ResultCallback.Adapter<>() {
                @Override
                public void onNext(Frame object) {
                    try {
                        String payloadString =
                                new String(object.getPayload(), StandardCharsets.UTF_8);
                        if (object.getStreamType() == StreamType.STDOUT) {
                            pipeOut.write(object.getPayload());
                        } else {
                            LOGGER.warn("Received STDERR from container {}: {}", containerId,
                                    payloadString);
                        }
                    } catch (IOException e) {
                        throw new UncheckedIOException(e);
                    }
                }
            });

        client.startContainerCmd(containerId).exec();
        return pipeIn;
    }
timber mirage
#
java.io.IOException: java.io.IOException: Le canal de communication a �t� ferm�
    at java.base/java.nio.channels.Channels$1.read(Channels.java:166) ~[na:na]
    at org.apache.hc.core5.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:149) ~[httpcore5-5.2.4.jar:5.2.4]
    at org.apache.hc.core5.http.impl.io.SessionInputBufferImpl.read(SessionInputBufferImpl.java:172) ~[httpcore5-5.2.4.jar:5.2.4]
    at org.apache.hc.core5.http.impl.io.IdentityInputStream.read(IdentityInputStream.java:91) ~[httpcore5-5.2.4.jar:5.2.4]
    at org.apache.hc.core5.http.io.EofSensorInputStream.read(EofSensorInputStream.java:118) ~[httpcore5-5.2.4.jar:5.2.4]
    at com.github.dockerjava.core.FramedInputStreamConsumer.accept(FramedInputStreamConsumer.java:30) ~[docker-java-core-3.3.6.jar:na]
    at com.github.dockerjava.core.FramedInputStreamConsumer.accept(FramedInputStreamConsumer.java:12) ~[docker-java-core-3.3.6.jar:na]
    at com.github.dockerjava.core.DefaultInvocationBuilder.lambda$executeAndStream$1(DefaultInvocationBuilder.java:275) ~[docker-java-core-3.3.6.jar:na]
    at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]
Caused by: java.io.IOException: Le canal de communication a �t� ferm�
    at java.base/sun.nio.ch.Iocp.translateErrorToIOException(Iocp.java:299) ~[na:na]
    at java.base/sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:389) ~[na:na]
    at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:113) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[na:na]
    ... 1 common frames omitted

@ebon river

sterile crest
#

update your docker version @timber mirage just to entertain me 😄

timber mirage
#

@ebon river the thread name is "docker-java-stream--676896705"

ebon river
#

I mean you could be a good boy and close the stream properly before killing the container

#

But apart from that I am not sure you can handle this gracefully

ebon river
#

How did you try that?

timber mirage
#

In fact, the container is closing itself

#

yet this happens

ebon river
#

I mean, the remote end probably disappears when the container closes

#

But maybe newer docker daemons are nicer about it

#

Updating might be worth a shot

#

Your docker is ~a year old

timber mirage
#

Nope

#

same problem

ebon river
#

With 24.0.9?

timber mirage
#

v27.1.1

ebon river
#

or 27.x?

sterile crest
#

ala, i'll jump in vc - check that my steps are the same as yours?

timber mirage
#

which steps ?

sterile crest
#

my repro steps

timber mirage
#

which steps ?

sterile crest
#

bruh

timber mirage
#

steps are literally

sterile crest
#

reproduction steps

timber mirage
#

there are no steps

#

unless you mean

  • bootRun
  • the curl I gave you
  • wait
sterile crest
#

if this isn't an issue for me and instan and it's not appearing on the vps

#

it's a you problem

timber mirage
#

We don't know if it is happening on the vps

ebon river
#

I think my thread just lives longer

#

And then dies afterwards

sterile crest
ebon river
#

Yea

sterile crest
#

but in any case, ignore the exception, there's nothing you can do besides thread.join

ebon river
#

And then the error is swallowed

sterile crest
#

you probably don't want to thread.join because i'm not sure what's happening under the hood

ebon river
#

I am not sure there is anything you can do honestly

#

At some random point your remote end disappears and you have no idea when or why

sterile crest
#

if it's a new thread per container, then you can otherwise, just swallow the error and leave it

ebon river
#

If you make a funny handshake close protocol you could store the closable in onStart and invoke it, ending the attachment stream

#

And only then exit the container

#

Simplest solution there is probably to make the container wait for a second or two before shutting itself down and stopping the stream in that period

timber mirage
#

I have no control on that

ebon river
#

client.attachContainerCmd

#

The frame adapter has a onStart method

#

And this is passed a closable which will close the underlying streams and streamer thread when invoked (using interrupts)

#

So you can gracefully exit the stdin/stdout/stderr streaming

sterile crest
#

@timber mirage you could try client.removeContainerCmd(containerId).exec();

#

sorry

#

maybe not

ebon river
#

The problem is that the remote end disappears

sterile crest
#

what's the inverse for attachContainerCmd?

ebon river
ebon river
timber mirage
#

this isn't normal

ebon river
#

You are streaming logs by opening a tcp connection to the docker daemon and you try to read from it

#

At some point the container says bye

#

And then the question is where in the protocol your client is stuck currently

#

Judging by the code in FramedInputStreamConsumer at least

sterile crest
#

@timber mirage try this:

ebon river
#

It should signal closure

sterile crest
#

                     client.attachContainerCmd(containerId)
                         .withLogs(true)
                         .withFollowStream(true)
                         .withStdOut(true)
                         .withStdErr(true)
                         .withStdIn(stdin)
                         .exec(new ResultCallback.Adapter<>() {
                             @Override
                             public void onNext(Frame object) {
                                 try {
                                     String payloadString =
                                             new String(object.getPayload(), StandardCharsets.UTF_8);
                                     if (object.getStreamType() == StreamType.STDOUT) {
                                         pipeOut.write(object.getPayload());
                                     } else {
                                         LOGGER.warn("Received STDERR from container {}: {}", containerId,
                                                 payloadString);
                                     }
                                 } catch (IOException e) {
                                     throw new UncheckedIOException(e);
                                 }
                             }

                             @Override
                             public void onComplete() {
                                 try {
                                     pipeOut.close();
                                     LOGGER.info("Stream from container {} closed successfully.", containerId);
                                 } catch (IOException e) {
                                     LOGGER.error("IOException while closing stream from container {}: {}", containerId, e.getMessage());
                                 }
                             }
                         });

#

added public void onComplete() { to the block

ebon river
#

On my machine you eventually receive an EOF in step 1

#

And then it gracefully shuts down

timber mirage
#

so what happens in my case ?

#

why do you not get this error ?

#

and also

#

I wish to know

#

Why I never got this problem before ?

sterile crest
#

environmental?

#

did you download a fortnite vbuck generator recently or something?

#

or maybe a windows update?

timber mirage
#

no

sterile crest
#

java version?

ebon river
#

You could set a logging breakpoint here maybe

#

And see what you get

sterile crest
#

I'm using java 21

ebon river
#

But it takes a while for the docker container to exit after the evaluation

sterile crest
#

are you using his branch @ebon river ?

ebon river
#

enhancement/improveclose

sterile crest
#

there were some changes made to the close functionality, instead we first mark is as "dead" controlled by a boolean and then there's a scheduled task to remove them

timber mirage
#

so why is this a problem only for me ?

sterile crest
#

ala, we don't know your system

#

you'll have to find the answer to that yourself

timber mirage
#

how am i even supposed to find such answer

ebon river
#

Add the logging breakpoint there maybe and see what you get

#

and how it correlates to the containers dying

timber mirage
#

wdym

timber mirage
ebon river
#

What do you mean?

timber mirage
#

What do you want me to do ?

sterile crest
#

at this point, you might have better chances in #1051826284008853505

timber mirage
#

ah

#

well

#

it got rid of the null characters

#

but imagine that there are null chars before the OK and a ton of null chars after the last line

timber mirage
#

@sterile crest @ebon river

#

how did you run it ?

#

I tried to run the api from inside docker

#

and I don't get the error

sterile crest
#
try {
  writer.close();
} finally {
  reader.close();
  try {
    reader.close();
  } finally {
    if(!dockerService.isDead(containerName())) {
      dockerService.killContainerByName(containerName());
    }
  }
}
#

while I get what you're trying to do...

#

it flipping sucks

timber mirage
#

Do you have a better idea ?

sterile crest
#
try {
  writer.close();
} catch(Exception e) {
  LOGGER.error("Failed to close writer", e);
}

try {
  reader.close();
} catch(Exception e) {
  LOGGER.error("Failed to close reader", e);
}

if(!dockerService.isDead(containerName())) {
  dockerService.killContainerByName(containerName());
}```
timber mirage
#

It's more redondant 🙂

sterile crest
#

yours is redundant

#

and worse

#

here's why

#

reader.close(); being called twice

#

that's redundant

timber mirage
#

wait

sterile crest
#

if one fails, you don't know which one - less observability

timber mirage
#

that's a typo

#
try {
  writer.close();
} finally {
  try {
    reader.close();
  } finally {
    if(!dockerService.isDead(containerName())) {
      dockerService.killContainerByName(containerName());
    }
  }
}
#

should have been this

#

anyway

#

I'll fix it

sterile crest
#

you're dong all this unnecessary try-finally nesting

#

but then again

#

your code is never readable so idc 😄

#

jshell is such a toy

timber mirage
#
    public void close() {
        try {
            writer.close();
        } catch (Exception ex) {
            LOGGER.error("Unexpected error while closing.", ex);
        }
        try {
            reader.close();
        } catch (Exception ex) {
            LOGGER.error("Unexpected error while closing.", ex);
        }
        try {
            if(!dockerService.isDead(containerName())) {
                dockerService.killContainerByName(containerName());
            }
        } catch (Exception ex) {
            LOGGER.error("Unexpected error while closing.", ex);
        }
        LOGGER.info("Session {} died.", id);
    }
#

alright

#

is it more readable tho 🤔

sterile crest
#

yes but your ordering of logging is wrong

#

LOGGER.info("Session {} died.", id); needs to go after if(!dockerService.isDead(containerName())) {

timber mirage
#

it is ?

sterile crest
#

yes because LOGGER.info("Session {} died.", id); will log even on failures

timber mirage
#

no

#

it must always log

#

whenever close is called

#

this log should fire

timber mirage
sterile crest
#

i did what you said

#

boot run

#

in intellij

#

no docker

timber mirage
#

weird

sterile crest
#

it working on docker means it's purely environmental when running locally :p

sterile crest
timber mirage
#

?

sterile crest
#

imagine seeing Session died in the log message

#

but all the code to kill the session exception

#

the session didn't die

timber mirage
#

then you would see the error just before

sterile crest
#

not if you're filtering by info messages

timber mirage
#

who would filter out errors ?

sterile crest
#

people who work on production systems and actually monitor logs using proper tool

timber mirage
#

no

sterile crest
#

it's not common practice to look at log messages in the console or just as a .txt file

timber mirage
#

nobody would filter out errors

#

it makes no sense

sterile crest
#

you need more profesional experience in software development

#

if you see:

#
error 
error
error
session died
#

okay errors idc about now because "session died"

#

but the session didn't die

#

but your logging told me the session died

timber mirage
#

well the session did die

#

the container maybe not

#

but the session did

sterile crest
#

your close method isn't killing a session then

#

your logging in the wrong area of the code

timber mirage
#

it is

sterile crest
#
    public void close() {
        LOGGER.info("Session {} died.", id);
    }````
#

this is what your code is doing

#

if we ignore the errors

timber mirage
#

I understand what you are saying

#

so I should move this log up a call

sterile crest
#

yeah 🙂

timber mirage
#

Alright, pushed

sterile crest
#

gradle spotlessApply

#

if(shouldDie()) throw new DockerException("Session %s is already dead.".formatted(id)); don't forget braces

#

and the error message should be different because the session is not dead explictly

sterile crest
#
        } catch (Exception ex) {
            LOGGER.error("Unexpected error while closing.", ex);
        }
        try {
            reader.close();
        } catch (Exception ex) {
            LOGGER.error("Unexpected error while closing.", ex);
        }
timber mirage
#

more complicated than that

sterile crest
#

put "Reader" and "Writer" in the messages for clarity

timber mirage
#

shouldDie -> session at least half dead

sterile crest
#

yeah

timber mirage
#

so the problem isn't here

#

but in the name shouldDie and markAsDead

sterile crest
#

"Session is no longer available because it's either dead or marked for removal"?

timber mirage
#

shouldDie -> at least irrecoverable, maybe totally dead
markAsDead -> has been marked for next heartbeat

timber mirage
#

like I said

#

the problem isn't this message here

#

since it is true

sterile crest
#

ok

timber mirage
#

but I could find anything better

sterile crest
#
 if(service.isMarkedAsDead()) {
                    try {
                        jshellSessions.remove(id).close();
                        LOGGER.info("Session {} died.", id);
                    } catch (Exception ex) {
                        LOGGER.error("Unexpected exception for session {}", id, ex);
                    }
                } else {
                    service.markAsDead();
                }
#

redunant else

#

session is already marked as dead

timber mirage
#

no

#

read the if again

sterile crest
#

ah yeah myb

#

Maybe this should be renamed: LOGGER.info("Session {} died.", id); to "Session has been removed"

#

actually

#

nevermind

#

its correct

#

forgot it's doing a close() too

#
public void deleteSession(String id) {
        jshellSessions.get(id).markAsDead();
    }
#

can we remove this and just use jshellSessions.get(id).markAsDead();

#

since it does the same thing

#

deleteSession != markAsDead

timber mirage
sterile crest
#

refactor the name?

timber mirage
#

I will take a pause

sterile crest
#

ok

timber mirage
#

Can you move to the pr and do an actual review please

#

instead of talking here

#

it will be lost

sterile crest
#

that's the last comment

timber mirage
sterile crest
#

He just has an emotional attachment to docker sessions @timber mirage

compact holly
#

should is a moral judgement, something that ought to be, compared to somhing that just is

#

it's like saying container deserves to die :(

#

you wish death upon it

timber mirage
compact holly
#

which is arguably worse than just killing it in self-defense

compact holly
sterile crest
#

No wonder we're having issues with containers dying

#

And the VPS not being cleaned up

#

Technology has feelings too

#

The TogetherJava VPS is supposed to be like heaven for tech, a nice safe place for them to live without the fear of dying

#

Now it's a graveyard of docker sessions 😦

timber mirage
sterile crest
#

We should be kind to our software, let's leave the containers running but they all can host their mini web servers and we can use spring to load balance

#

Actually, we should have done that

sterile crest
#

They must burn!!

timber mirage
#

anyway #chit-chat

bright lark
#

yoo

#

sorry for being late I had a time issue today while checking-out from hotel .. anyway

#

is it solved ?

timber mirage
#

no

compact holly
bright lark
#

alright, based on the discussion above

#

it looks that alathreon is only one having the issue

#

without knowing yet how it happens

sterile crest
#

well spotted

bright lark
#

that means, ala has something causing the issue

#

it would be useful if somebody having a no issue version, to assist ala via a tool like rdp

sterile crest
#

excellent idea, any tools you recommend? maybe you can rdp onto his machine and investigate

bright lark
#

i mean to reinstall whole app

#

ye why not

#

but not today, as i dnt have much time

#

i m still checking the changes and learning about docker api

#

gotta sleep early too

bright lark
#

I keep getting these logs without doing anything yet

#
2024-08-05T22:20:09.172+01:00  INFO 21452 --- [pool-2-thread-1] o.t.j.service.JShellSessionService       : Scheduler heartbeat: started.
2024-08-05T22:20:09.173+01:00  INFO 21452 --- [pool-2-thread-1] o.t.j.service.JShellSessionService       : Scheduler heartbeat: sessions ready to die: []
2024-08-05T22:21:09.158+01:00  INFO 21452 --- [pool-2-thread-1] o.t.j.service.JShellSessionService       : Scheduler heartbeat: started.
2024-08-05T22:21:09.158+01:00  INFO 21452 --- [pool-2-thread-1] o.t.j.service.JShellSessionService       : Scheduler heartbeat: sessions ready to die: []
#

is this normal ?

compact holly
#

we all should be ready to die

#

I think sessions just adopted philosophy of the great Stoics

#

so looks pretty normal to me

#

they don't seem depressive or suicidal, just mentally built different, strong gigachad

#

not scared of the future, calm and ready

bright lark
#

it doesn't make sense to me

#

why would i get logs why i didn't nothing

compact holly
#

logs are more detailed, to help you with debugging peepo_happy

#

you can pick and choose the log level to your liking

bright lark
#

the level is info and those logs are infos

#

it would better to switch them to debug lvl

#

JShellSessionService looks too complex ngl

#

alright, it seems that im gonna be stuck with the current code base

#

as there are no comments, in addition to some ugly stuff

#

in fact alathreon is not the only one who notice the errors

#

i had some errors too, and they're mysteriously gone

#

as this is 1st time i try such project, i think it'd be better for me to exercice a bit

#

so i'm gonna try a sample with similar objectives, but in minimal shape

#

will come back with updates

compact holly
#

if you can reproduce the issues, you can go trough it with a debugger

#

that way you can see what is happening and you can follow the flow

bright lark
#

i'm unable to understand the current codebase

#

it's too new to me, or maybe some parts are ugly

compact holly
#

yeah, it's somewhat complex

bright lark
#

spaghetti code

compact holly
#

what do you feel is lacking?

#

you can ask ala for explanation of parts that are confusing

#

try to follow the flow of the command with debugger

bright lark
#

that will not help as i may re-ask anytime

compact holly
#

to get the bigger picture how the system works

#

it takes time to get familiar

bright lark
#

i think that's why

#

not many people came

#

it lacks clarity

#

opensource project without documentation is like private

#

im gonna build a very basic sample that works properly

#

after that i may come again

timber mirage
timber mirage
timber mirage
bright lark
#

actually it confuses me

timber mirage
timber mirage
timber mirage
bright lark
#

i expect it to be in the list to die

#

but the logs keeps saying

sessions ready to die []

timber mirage
#

wdym

timber mirage
bright lark
#

the session is up

timber mirage
#

yes

bright lark
#

and ready to die

timber mirage
#

nope

#

sessions have a lifetime of 30min by default

#

after those 30 minutes, they will die

bright lark
#

ye but it could die earlier

timber mirage
#

well no

bright lark
#

what

#

😵‍💫

timber mirage
#

the idea is to keep the session alive, so the user could use the previous statements and add new ones

#

or also read their own statements

#

So you could sent a request which contains a class

timber mirage
#

and then a request to execute code using this class

bright lark
#

as i said earlier some parts are hard to read (complex)

timber mirage
bright lark
#

and i dun't know how to simplify them

timber mirage
#

(it's not up to date but at least the general idea still works)

bright lark
#

im still learning

timber mirage
timber mirage
#

Remember, it's no up to date, but at least the general idea is still here

bright lark
#

oh damn

#

it's since 2023

bright lark
#

anyway, np

#

im gonna exercice with a minimal sample

#

i need to do tht

timber mirage
#

like

#

collapse everything

#

and look at it like you would look at an interface

#

only see public

#

and even ignore bodies

compact holly
#

i advise you to follow the command with debugger, and see how it works, the flow

timber mirage
#

should help a lot

compact holly
#

to get the familiarty and see how the systems fits together

timber mirage
compact holly
#

debugger offers a lot of cool tools

bright lark
#

i know i can do it

compact holly
#

and you get annotated values

timber mirage
#

well yea, a debugger would make it even easier

compact holly
#

so it's easier to follow and play with the codebase

bright lark
#

i knooow

compact holly
#

but yeah, whatever you are more comfy with

bright lark
#

ok

#

ill try tht tomorrow, cuz now im all in

#

thanks

timber mirage
#

wdym

#

if you are all in

#

how can you try this tomorrow ?

bright lark
#

oh

#

i thought it's an idium to tell tht im tired

#

forget it surprised

timber mirage
#

🤷

sterile crest
#

Firas struggling to read code?? peepo_think peepo_think

#

He's one of our top expert members too, so there must be really deep rooted problems

sterile crest
#

i'm just playing, not making fun of you, you're right about some of the observations

bright lark
#

Today gonna full debug

#

my 1st lesson in tj-jshell

#

As for the future it would be nice to create a website for it

#

A playground with file explorer would be great

timber mirage
bright lark
#

But what if we think about extension?

#

It would be cool, like codesandbox

#

It's in same context ig

timber mirage
bright lark
#

i think about writing a schema.json openapi for the api

#

without need to the springboot openapi dependency

#

thus, the controller's code can rest without additional annotations

#

the schema can be used in swagger ui playground

compact holly
#

someone already did that iirc, but ala disliked it, check PRs

timber mirage
compact holly
#

ah, without annotations

bright lark
#

yes

timber mirage
#

There might be ways

#

Like create an interface with swagger annotations

#

so it's splitted between the code and swagger

bright lark
#

my approach is to split schema from from java code

#

but it must be something to validate

#

so maybe yes

timber mirage
#

So if you wan't, you can study this idea

bright lark
#

got it

#

is there precommit hook?

timber mirage
#

I don't think so

bright lark
#

we need to set that up

compact holly
#

also sonar and other tooling

#

sonar will probably raise a lot of issues that would need to be addressed

sterile crest
#

we don't need an openapi spec right now

#

the focus should be purely on the functional aspects, like making sure it works

compact holly
#

let firas cook

#

documented api is sexy

bright lark
#

It just came to my mind and wanted to share

bright lark
#

hi again

#

do i pick develop branch ?

timber mirage
bright lark
#

oh boy

#

so session are kept in memory

#
private final Map<String, JShellService> jshellSessions = new HashMap<>();
#

i dnt get this

#

jShellService is a spring bean

#

it's the 1st time i see this

#

ah JShellService refers to session?

#

the name is ambiguous

#

is it ok to write some comments and rename some methods to make names have more sense ?

#

another question: why there are no entities ?!

#

alright im going to make some changes in a separate branch

#

and PR

sterile crest
compact holly
#

what do you think about architecture and layering?

bright lark
compact holly
#

more vertical or horizontal

#

maybe we should do domain driven development with hexagonal architecture?

#

how would you do it?

bright lark
#

oh nice

compact holly
#

or standard model service repository or whatever

bright lark
#

well it could be simple

#

but why we don't start with a basic mvc

compact holly
#

hm..

#

which database would we go for?

bright lark
#

no need to

#

the app doesn't require a db

#

everything is in memory

compact holly
#

right, we can just use json config

bright lark
#

wdym by that?

sterile crest
compact holly
#

if bot dies, all sessions are lost

bright lark
compact holly
#

or when we deploy new version

bright lark
#

the current impl can work without db ig

compact holly
#

it restarts

#

kinda fragile

bright lark
compact holly
#

right

bright lark
#

then we should add orm, db and entities

compact holly
#

maybe containers would infiniteky accumukate, because they wouldn't be kilked

bright lark
#

however, id add entities package even without db

compact holly
#

coz inmemory state got lost :(

#

what do you think about redis?

bright lark
#

cache tool

#

ah i heard about it

#

never used it

#

id go to firebase

#

it gives lota options

quartz shell
#

Redis would be nice, especially if u are just using it for caching.

bright lark
#

oh it's not free

sterile crest
#

maybe we can use neo4j

#

it's a graph based db

#

it's the best performing graph db and it's also java based

#

it supports generative AI now

bright lark
#

sure , but i dnt see this as priority now

#

correct me if im wrong

sterile crest
#

we can replace the HashMap with this

quartz shell
#

firebase is paid

sterile crest
quartz shell
#

you can just spin up a docker container

sterile crest
#

free means it's not gonna be good

bright lark
#

i can't see a free plan

quartz shell
bright lark
#

that depends on @compact holly

quartz shell
bright lark
#

alright, we're getting faraway from objectives

#

we'll get back to this as soon as we fix the current version of the app

quartz shell
compact holly
#

you will se those have the VpsAccess role peepo_happy

compact holly
#

what is the current issue you are having?

timber mirage
timber mirage
timber mirage
sterile crest
#

we need a DB

#

or something for an audit history

timber mirage
#

We can do that in tj bot side

#

Well

sterile crest
#

not if we have firas idea of multiple consumers

timber mirage
#

yes indeed

sterile crest
#

anyways that's all free with AWS geniusidea

compact holly
#

"why we have this API, we don't need it blah blah"

#

you simply did not see the bigger picture firas did

timber mirage
#

me*

compact holly
#

we will have a magnificent website where people could run their code on

#

and maybe even embed our code runner to their sites

#

that will promote our community

#

and create backlinks

sterile crest
#

the problem with an API is that there's additional latency and overhead

compact holly
#

ah, the performance

sterile crest
#

for a performant system, we'd want it event driven

#

and use a message bus

timber mirage
sterile crest
#

like Kafka

compact holly
#

we can't spare 3ms of latency peepo_cry

sterile crest
#

you can't scale the API with the current infra

compact holly
#

he claims its free peepo_happy

sterile crest
#

it is free

#

i've shown you evidence

compact holly
#

see

timber mirage
compact holly
#

millions of daily users for free

#

but yes, imagine every technical blog having our code runner exampels embedded

sterile crest
compact holly
#

togetherjava will become intergalactically famous and respected

sterile crest
#

then they can bill you properly

#

for TJ and small businesses, it's perfectly fine

#

i can even make a serverless discord bot

#

the thing that keeps a discord bot showing as "online" is the heartbeat, you can use AWS EventBridge scheduler for that

#

and use AWS APIGW Authorizer for serverless web socket events

#

or use EventBridge to wake up when it receives an event

compact holly
#

we declare bankrupcy, and whoop, it's gone peepo_happy

sterile crest
#

our usage is so small anyway

compact holly
#

that's how dept works in us at least

#

yeah, but you are not imagining the world firas does

#

in firas world, we are large and respected organizaton

#

we have a website where you can run code with our jshell api

#

and my idea is to make it embeddable in every website, or tool that needs to run code

#

so every blog uses our tech, stackoverflow answer

#

to we become internationally famous

sterile crest
#

well if we used my original "just give the user an entire linux container"

compact holly
#

then we host events with brian goetz

#

gets funding from oracle... etc

sterile crest
#

then we have unlimited possibilites

compact holly
#

firas world is big picture world

sterile crest
#

bro

#

what about the mobile app??

compact holly
#

well if it work in web, it works on phones as well

sterile crest
#

we can get my guys to create an app using jetpack compose and it'll let people run our jshell service too

compact holly
#

we can scam people with some electron bs

sterile crest
#

we want native apps

#

none of that website stuff

sterile crest
compact holly
#

right, some people would ask who runs java code on their phone

#

and our answer should whoever wants

#

we did it because we could, to prove our technical superiority

compact holly
#

1 contributor

#

ah, its your project

sterile crest
#

the wazei web framework

compact holly
#

riight, all wazei stack

sterile crest
#

exactlyyyy

#
public class HelloController {
    /**
     * ---
     * $method=get
     * $path=/hello
     * $content-type=application/text
     * ---
     */
    public String hello(String nameParam) {
        return "Hello, %s!".formatted(nameParam);
    }
}
#

look at that

#

your comments control logic

compact holly
#

anyway, once we host brian goetz here on the server

sterile crest
#

or if you dont like commenting your code

#
public class HelloController {
   public String greet(String name) {
     return "Hello, %s!".formatted(nameParam);
   }
}```
compact holly
#

we can help him make project loom and panama happen

sterile crest
#

bunch of exmples too

#

it's a very professional product

compact holly
#

i have no doubts :D

sterile crest
#

: D : D

compact holly
#

riight

sterile crest
#

it comes with built in monitoring and metric collection

#
System.out.println(promise.getMetrics()); // To get metrics of a Promise
// > PromiseMetrics{start=140720275666100, end=140720275677900, success=true, executionTime=11800, memoryUsage=0, errorDetails='', stackTrace=[]}
compact holly
#

well tested, and lots of users

#

i assume

sterile crest
#

exactly

#

the wazei stack

#

@compact holly

#

u wanted RDP right??

compact holly
#

are these actually real links?

sterile crest
#

yes

#

click them

compact holly
#

you created random projects to spice up your CV?

sterile crest
#

yup

#

LOL

#

even a video preview

compact holly
#

soon you will have more libs than ethan lol

sterile crest
#

my libs are more fun

#

a bit more complicated

compact holly
#

ah, more sphisticated

sterile crest
#

but at least I'm not just repackaging existing libs

#

u should see my private repo's

#

like this one

compact holly
#

rather not

sterile crest
#

u can test an API using Socks5 proxy

#

so when we wanna simulate real users

#

i gotchu

#

This repository contains 290 open Socks5 servers that are available for use.

#
        /*
         * Call our example REST API call 10 times for each proxy.
         * Since there are 290 registered proxies, all 290 servers will run our request
         * 10 times sequentially.
         */
        socks5.run(10, exampleSocks5);
compact holly
#

in your privte repos

sterile crest
compact holly
#

was cutting edge AI tech at it's time

sterile crest
#

if u want

compact holly
#

is that your project as well?

sterile crest
#

it uses Azure Voice under the hood

#

Yes

#

I have all the codes bro

quartz shell
#

ui

sterile crest
#

LOOL

compact holly
#

you are actually a modern day leonardo da vinci

#

true genius and polymath\

quartz shell
#

incredible

sterile crest
#

i also made this "route to mic" feature which lets you pipe the audio from azure voice to in game chat

#

great for those people shy to talk but still wanna use ingame coms

compact holly
#

how many stars does that project have?

sterile crest
#

its private

#

i wanted to sell it but i cba set it up

compact holly
#

shame, your genius was never appreciated :(

#

people don't see the real wazei

sterile crest
#

😄

#

i told u fun projects 😄

compact holly
#

do you have any uwu intellij extensions?

#

you know, moral support while you write code

#

someone to cheer you on when our shit finally compiles

sterile crest
#

i actually replaced all my icons with ur profile pic

compact holly
#

wh

#

i'm changing my pfp

sterile crest
#

ty, i needed an icon change

compact holly
#

ohh, intellij plugin for jshell

#

so you can run jshell in your intellij

sterile crest
#

😄

compact holly
#

maybe enable partial compilation

sterile crest
#

i made u my start icon

compact holly
#

so you can compile justone method

#

and run it

#

and not having to build whole ass thing

#

for quick testing and protyping on larger projects

sterile crest
#

marko u like anime stuff right?

compact holly
#

our jshell will make a revolution in the industry

compact holly
#

but evne if it's sexual, at least you are happy peepo_happy

sterile crest
#

if you send a message e.g. -hug- @wazei - it'll send an embed with an anime hugging gif saying "marko hugged wazei"

compact holly
#

why would I buy if you just sent me the codes, dummy cool

#

never thought hacking would be this easy

sterile crest
#

you can't compile 😄

compact holly
#

we need uwu voice reading jshell code posted on the server

#

for the blind users

sterile crest
quartz shell
compact holly
#

any code*

sterile crest
#

i can teach u how to use azure voice once firas does his azure migration

#

anyways

#

enough shit posting

compact holly
#

that would have to be a premium feature

quartz shell
#

why are we swithing to azure not alibidbaba

sterile crest
compact holly
#

weebs are easy target to get some monies

sterile crest
quartz shell
sterile crest
#

gcp kinda sucks ass

quartz shell
#

I find it's interface hard to navigate

#

compared to aws

sterile crest
#

my cloud journey started gcp>azure>aws

sterile crest
#

i never was happy with gcp, back when i was a google fan boy, i did my best to love their products

#

but gcp was aids

compact holly
#

i self-host everything gigachad

#

so I have my own cloud

sterile crest
#

what if a meteor hits ur server?

compact holly
#

then it would hit me too, so I wouldn't care gigachad

sterile crest
#

okay ill ask firas to put that down as part of our risk mitigation diagram

#

i think the idea was to run a really long USB cable from your house to his?

compact holly
#

i think elon musk has some satelite space dishes

#

dunno

sterile crest
#

actually, it's possible if we become tier 1 ISP

#

or tier 3 can't remember which one digs up the ground and lays cable s

compact holly
#

ye, it's easy to be ISP

#

people done it locally, because monopolies

#

basically fancy wifi

sterile crest
#

i looked into doing it before but it wasn't cost effective

compact holly
#

and you can have 10gbit/s connections

sterile crest
#

you can't

compact holly
#

it's not some shitty tech

sterile crest
#

it's not that easy

#

if you don't have the physical cables, they need to be laid

vivid cliff
compact holly
#

you use air

#

modern tech is crazy

vivid cliff
#

usb signal has to be repeated much much more

#

every 20 ft ig

compact holly
#

right, wazei idea wasn't smart

#

usb is not good

sterile crest
#

it wasn't my idea

sterile crest
#

sorry ala

#

we're off topic

timber mirage
#

@compact holly @sterile crest please I am tired, stop going offtopic here

sterile crest
#

so what's the topic on jshell ala?

timber mirage
#

?

compact holly
#

so this thin

sterile crest
#

is there something u wanna talk about around jshel?

compact holly
#

you can just shoot internet to pepople trough air

#

and they can have 1 or 10gbit

#

no issues

#

it's cheaper to set up, because you don't need to dig up the infra

#

but more expansive over the long run

sterile crest
#

but how would u get 10gig

compact holly
#

these are powerful

sterile crest
#

connected to what host?

compact holly
#

not same wifi crap tech

sterile crest
#

u still need a physical 10gig somewhere

timber mirage
sterile crest
#

😄

timber mirage
compact holly
#

i mean yeah

#

but no digging the whole city

#

you shoot internet from one place to the user

sterile crest
#

but i live in the UK

compact holly
#

well from many places

sterile crest
#

we don't have 10gig

#

we need to dig it up the tier 1

compact holly
#

ah, that sucks

sterile crest
#

so from my house we need a long cable leaving our island?

#

just dig a hole through the middle of the UK 😄

compact holly
#

i pay $10 for gigabit

#

10gig would be maybe $20, dunno

#

shit's cheap

#

multiple fiber providers in my building, so strong competition

#

actually 1 isp called me 10 today

#

so aggressive, offering me 250mbit and iptv for free

#

for 2 yeras

#

in the hope that I will stay with them afterwards or something

#

I was thinking to maybe have another network with servers with that connection

#

but can't be bothered with all that bs

#

it's free tho :/

#

could be used for good

#

anyway, this doesn't help us with jshell

#

@bright lark, what's your progress

#

update us

compact holly
sterile crest
#

not that u could afford it

compact holly
#

having to do cabling through ocean is pain in the ass

sterile crest
#

yup

#

we're getting there though

compact holly
#

poor austrailans get triple fucked

#

they have 300 ping in most games, ozon holes give them cancer

#

they live upside down, and the wildlife is very hostile

#

living life on nightmare diffuculty

bright lark
#

i don't know why u enjoy talking about offtopic here

#

ive done some debugging to understand the flow of the app. I ve tried the /jshel/eval/{id}

#

the docs helped me to get closer

#

however, i notice some weird patterns

#

like injecting docker and session services into the model JShellService

#

this could lead to errors or circular deps

#

also some method names look ambiguous. some conditions are duplicated unnecessarily

#

it seems that the project was created quickly without thinking too much about maintainability

#

JShellService constructor takes 12 args !

#

as i said previously, the hard part is thinking, code is the easiest part

#

so i may add some diagrams to show the actors, uc and flows

bright lark
bright lark
bright lark
timber mirage
timber mirage
bright lark
timber mirage
bright lark
#

duplicated condition

 if (!hasSession(id)) { }
timber mirage
bright lark
#

a method name must indicate a behavior. session doesn't seem clear

#

oneTimeSession() too

#

as for createSession() it looks fine

timber mirage
bright lark
#

im going to do something

#

ig tonight

#

and will share in pr

bright lark
timber mirage
#

too complex for a name

bright lark
#

Idnt think so, it looks clear

#

The method adds a session or update an existing one

#

Maybe a more clear name is createOrReuse()

#

Also session id should be provided by the system

#

Not by client

#

So if id is null, tht means NEW, if it's not null, it means reuse/update

timber mirage
bright lark
#

Lmao

#

What do u suggest then?

#

Maybe we should split them

#

Into 2 endpoints

#

POST/session and PUT/session

timber mirage
#

sessions should automatically be created

#

And

#

fetchSession is a correct name

bright lark
#

the name confuses reader

#

im typically creating a session, so method must be create() or add()

#

while when i fetch an existing one, i may use something else like fetch() or get()

#

🤷‍♂️

timber mirage
timber mirage
bright lark
#

but we should change the name of session()

timber mirage
#

Or find

bright lark
#

createOrFetch

timber mirage
#

No fetch

#

You don't need to know that it was created

bright lark
#

how's tht?

timber mirage
#

And even then, it is included in the word fetch

bright lark
#

i dnt think so

#

fetch means get

timber mirage
bright lark
#

imo we need to have 2 methods in JShellSessionService

#

and call right one based on the args

#
if(newId){
  return create();
}
return fetch();
#

also, im not certain that providing id from client is ok

timber mirage
bright lark
#

not exaclty, session() has drawbacks

#

redundant condition

#

and confusing name

timber mirage
#

How is it redundant?

timber mirage
bright lark
#

in createSession()

timber mirage
bright lark
#

i mean this if (hasSession(sessionInfo.id())) {}

timber mirage
#

Sorry I don't have the code under my eyes

#

Alternatively you could call it obtainSession

bright lark
#
public JShellService session(String id, @Nullable StartupScriptId startupScriptId) throws DockerException {
     if (!hasSession(id)) {
       return createSession(new SessionInfo(id, true, startupScriptId, false, config));
     }
     return jshellSessions.get(id);
}
timber mirage
#

Right, and createSession?

bright lark
#

in createSession the same condition but opposite

#

i dnt know why exactly

timber mirage
#

Show it please

#

Is it a fail-fast?

bright lark
#
private synchronized JShellService createSession(SessionInfo sessionInfo) throws DockerException {
    // Just in case race condition happens just before createSession
    if (hasSession(sessionInfo.id())) { }
}
#

even the comment is not signficant

timber mirage
#

But what does it do?

#

Does it fail fast?

bright lark
#

i think yetserday when i tried it

#

for my 1st session, it was false

timber mirage
#

Wdym you don't recall? Do you not remember the code, do you not have the code under your eyes?

timber mirage
bright lark
#

but can't run it

timber mirage
#

Please show the code

bright lark
#

i did

timber mirage
#

No you didn't

bright lark
#

there is a collision between session() and createSession()

timber mirage
#

You cut the part I asked

timber mirage
bright lark
#
private synchronized JShellService createSession(SessionInfo sessionInfo)
    throws DockerException {
    // Just in case race condition happens just before createSession
    if (hasSession(sessionInfo.id())) {
        return jshellSessions.get(sessionInfo.id());
    }
    if (jshellSessions.size() >= config.maxAliveSessions()) {
        throw new ResponseStatusException(HttpStatus.TOO_MANY_REQUESTS,
            "Too many sessions, try again later :(.");
    }
    LOGGER.info("Creating session : {}.", sessionInfo);
    JShellService service = new JShellService(dockerService, this, sessionInfo.id(),
        sessionInfo.sessionTimeout(), sessionInfo.renewable(), sessionInfo.evalTimeout(),
        sessionInfo.evalTimeoutValidationLeeway(), sessionInfo.sysOutCharLimit(),
        config.dockerMaxRamMegaBytes(), config.dockerCPUsUsage(), config.dockerCPUSetCPUs(),
        startupScriptsService.get(sessionInfo.startupScriptId()));
    jshellSessions.put(sessionInfo.id(), service);
    return service;
}
#
public JShellService session(String id, @Nullable StartupScriptId startupScriptId)
    throws DockerException {
    if (!hasSession(id)) {
        return createSession(new SessionInfo(id, true, startupScriptId, false, config));
    }
    return jshellSessions.get(id);
}

public JShellService session(@Nullable StartupScriptId startupScriptId) throws DockerException {
    return createSession(new SessionInfo(UUID.randomUUID().toString(), false, startupScriptId,
        false, config));
}
#

session() has 2 versions

timber mirage
#

Ah I see

#

Yes it's to avoid a race condition

#

Alternative would be to extract this if into session and add an additional sync block here

timber mirage
bright lark
timber mirage
# bright lark wdym

There is a chance two threads arrive on the if in session at the same and so try to create a session for same id

bright lark
#

let's get rid of session() then

timber mirage
timber mirage
bright lark
#

which means the method cannot have multiple threads on it at a time

#

so i dnt get what u mean by

it is syncronized and so it doesn't scale well

#

btw i think that createSession is an async operation as it waits a response from docker

timber mirage
bright lark
#

how about using @Async

timber mirage
bright lark
timber mirage
#

Ah and because of makro and wazei oftopic, I can't find what they said last time

#

@sterile crest can your review my pr please ?

bright lark
#

ive read tht @Async in spring is helpful to assert one thread handles async operation

#

is tht unrelevant

timber mirage
#

This is unrelated

#

So

#

next priority are tests

bright lark
#

oh really

#

are the bugs still showing up ?

timber mirage
#

no

bright lark
#

ohboy

#

how ?

timber mirage
#

well

#

we will know that once it reaches prod

sterile crest
#

are u able to force merge ur PRs @timber mirage ?

sterile crest
#

ah okay

timber mirage
#

I am waiting for a review

bright lark
#

do u want me to join ?

#

otherwise i continue my work

timber mirage
bright lark
timber mirage
bright lark
#

alr

#

i pick any ?

timber mirage
#

what ?

bright lark
#

do i pick any pr

#

or u want to focus on specific one

timber mirage
#

We were talking about my pr

bright lark
#

u have more than one

timber mirage
#

about revewing my pr

bright lark
timber mirage
#

Ah yes

#

well review all of mine yes

#

also if you want real work

#

do the tests

bright lark
#

as i said previously, there are some weird stuff

#

and i gave examples

#

tests could be done when there is clean stable codebase