| 
  • If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • You already know Dokkio is an AI-powered assistant to organize & manage your digital files & messages. Very soon, Dokkio will support Outlook as well as One Drive. Check it out today!

View
 

REPLServer

Page history last edited by Michael van der Gulik 11 years ago

REPLServer

 

I.e. Read-eval-print-loop server.

 

REPLServer is a telnet server that gives you access to a Smalltalk command-line interface. It gives you a back door into a Squeak image to rescue it when, for example, Morphic dies.

 

Install it from the Universes Browser in Squeak, under the "Network" category.

 

Code is on http://squeaksource.com/SecureSqueak/.

 

(TODO: more docs here)

 

REPL CLI for SecureSqueak

 

The code for REPLServer should be generic enough to be usable with SecureSqueak. This will take the place of the "emergency evaluator" and can be accessed either via telnet or from a particular emergency keypress on the console (re-use alt-. maybe?).

 

An example session, fabricated to throw ideas around:

 

: dominions.

(will list dominions here).

 

: d := dominions at: 4.

a Dominion ('chatservice')

 

: d suspend.

a Dominion ('chatservice') (suspended)

 

: p := Processor processes. "or something like that?"

(will list processes)

 

: ps := p at: 2.

a Process in dominion 'chatservice'.

 

: ps suspend.

 

: d := Debugger on: ps.

 

" assume each of these commands have output associated with them. "

: d n. "next instruction; a labourious process!"

: d n.

: d list.

: d valueOf: 'bob'. "Shows the value of bob"

: d bt. "Backtrace"

: d breakAt: 4. "breakpoint at line 4. Perhaps breakpoints are only valid for one method?"

: d c. "Continue".

 

How would you modify methods in this debugger?

 

Debugging in SecureSqueak will be done by attaching a debugger to a process. A graphical debugger would perhaps show a list of all processes which the user can suspend and debug.

 

 

Managing background threads

 

A command line can be swamped out of usability by a >>printOn: method that stalls, or a >>printOn: method which produces too much output. The output is from trying to convert the result (an object of some sort) to a String using the printOn: methods et al.

 

To prevent stalled interactivity, commands should be run in a separate Process, and the output is sent to a stream somehow. If those commands don't finish in, say, one second, then the output stream blocks the progress of that thread (i.e. nextPutAll>> just waits for the user to ask for more).

 

To prevent too much output, the output stream only shows a certain number of lines on the screen. After that, the user must prompt it to show more.

 

Alternatively, just send all output to the screen and wait for the 1 second timeout to occur; hopefully the buffers between the running command and the screen output won't be able to swamp a slow remote connection for much more than 1 second.

 

Alternatively, limit the output to 20 lines, requiring the user to find some other way of displaying it? No, sometimes you really do want to print an entire Dictionary or Array.

 

Thoughts:

  • Perhaps this could be related to the command history. Each history item has the typed in command and an output buffer.
  • Output buffers could be limited to one screenfull of information after which they will block whatever is writing to them?
  • The user should perhaps be notified when a background Process has completed?

 

For example:

 

: someObject verbage.

(pause 1 second)

 

No output in 1 second, process forked in background.

Output available as "lastOutput"; to keep output you will need to bind this to another variable.

( or maybe use the history to get at these values?).

 

: o := lastOutput.

: o nextLines: 40. " Show the next 40 lines of text ".

... 40 lines of text here...

( but then won't you end up with two chained outputs? )

: o suspend. " Suspends the process as well. "

: o resume. " Resumes the process as well. "

: o process.

a Process(bla).

: o linesFrom: 10 to: 30.

... displays lines 10 to 30...

: o.

an OutputStream (567 lines).

: o all.

... shows all output from o...

: o n.

"Show the next 25 lines (i.e. one screenfull)."

 

: something unrelated...

an Object (or something).

 

Process for command at "history at: 26" has finished.

 

: h := history at: 26.

A Command ("someObject verbage").

 

: o := h output.

an OutputStream(6882 lines)

 

: h process

a Process(terminated).

 

: h timeToRun. "er... maybe?"

Completed at 4:26pm (23 minutes run time).

 

 

Alternative, blocking using command history:

 

1: someObject longTimeWaiting.

No response in 1 second. Process forked and result will be available in "(history at: 1) result".

 

2: history at: 1.

A command ("someObject longTimeWaiting").

 

3: (history at: 1) result. "A future."

 

... later ...

 

Command 1 completed, see "(history at: 1) result".

Command 3 completed, see "(history at: 3) result".

 

6: (history at: 1) result.

 

some Object.

 

7: (history at: 3) result.

some Object.

 

...later...

100: something something.

 

Your history is getting large. Consider clearing it with "history clear".

 

 

Verbage blocking:

 

: someObject verbage.

(output here is truncated at say 25 lines).

 

Output truncated; use "p := Pager on: last" to view all output.

 

: p := Pager on: last.

(First 25 lines of someObject verbage).

 

: p next.

(Next 25 lines of someObject verbage).

 

: p tail.

(Last 25 lines of someObject verbage).

 

: p find: 'search-text'.

1: line 25: ...text...

2: line 26: ...text...

(etc for 23 lines)

Output truncated; use "p := Pager on: last" to view all output.

 

: last at: 2.

a String(...text...)

 

 

Command History

 

The REPLServer already supports command history.

 

The command history is an ordered collection of indexed commands. Ideally, the indexes will remain the same between commands such that "history at: 32" is always the same command.

Perhaps a warning could be sent to the user when the history gets too big asking the user to clear the history?

 

Each command would have:

  • The text of that command.
  • The result of that command.

 

Interaction

 

Sometimes applications will need to ask the user a question. For example:

 

: do something

Are you sure? Yes / No

 

: ui yes.

 

Perhaps there should be a binding to a ui object which can have messages sent to it to provide feedback?

 

: ui yes.

: ui no.

: ui cancel.

: ui answerString: 'some-string'.

 

The ui would be a stack of unanswered questions perhaps?

 

I don't want to have any direct interaction with the user requiring special key combinations (CTRL-c, CTRL-z from bash) to escape from it.

For example, I don't want an object to be able to block the "user interface".

 

Managing Namespaces

 

The CLI will need its own manageable import list for importing namespaces. By default, this should include complete control over the system such as access to the objects which control system state (SystemDictionary?).

 

Should it have access to the package manager? That is really a developer's tool.

 

26: s := String new.

 

Q: Import Collections from CollectionsPackage v6?

Respond with "ui yes" or "ui no".

 

27: ui yes.

true.

 

Command 26 completed with result:

a String('')

 

28: importList.

an OrderedCollection (...).

 

29: importList value remove: (importList at: 3).

an OrderedCollection(...).

 

Replacing an OS Shell, e.g. bash.

 

This is difficult unless direct input and output is possible from the console.

 

 

1: f cwd.

a FileDirectory(/home/mikevdg/tmp).

 

2: f back.

a FileDirectory(/home/mikevdg)

 

3: f openFile: 'readme.txt'.

a File(/home/mikevdg/readme.txt')

 

4: f exec: 'cat' args: 'readme.txt'; pipe: ... "or something?"

 

How would you do input from the console?

 

5: command := f command: '/usr/bin/cat'.

6: command stdin nextPutAll: 'hello world'.

7: command stdout next:100.

...

hmm... I don't know. It isn't well suited to this environment.

 

 

Comments (0)

You don't have permission to comment on this page.