Puzzle: Adding domain-based security to Squeak.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
37 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: Puzzle: Adding domain-based security to Squeak.

Michael Roberts-2

On 8 Aug 2006, at 10:03, Michael van der Gulik wrote:

> Hi Howard.
>
> I forgot to mention that the reason I'm doing this is to allow  
> untrusted foreign code to run in the same image as trusted code.  
> Untrusted code must be carefully managed - it must not be able to  
> consume large amounts of memory, CPU or disk space to which it is  
> not entitled. Untrusted code / objects must not prevent trusted  
> code from operating well.

This is not exactly what you asked for, but -

as an experiment why not run your untrusted code in a separate  
image?  If you were running this on unix then you could limit the  
memory given to this separate image - either via say ulimit in the  
shell or something fancier (maybe via the os process plugin).  You  
could then talk to the 'jail' image via remote messaging.  It  
wouldn't take very long to knock up and it might give you interesting  
results early.

As for limiting CPU or disk space that's a bit harder but there are  
various things you could do on Linux to try it out.  Run a separate  
squeak image inside User Mode Linux for example.  That would allow  
finer control of virtual CPU and disk space.

Cheers,

Mike

Reply | Threaded
Open this post in threaded view
|

Re: Puzzle: Adding domain-based security to Squeak.

Klaus D. Witzel
In reply to this post by Howard Stearns
On Tue, 08 Aug 2006 18:04:07 +0200, Howard Stearns wrote:

> Klaus D. Witzel wrote:
>> On Tue, 08 Aug 2006 16:53:46 +0200, Howard Stearns wrote:
>>
>>> Imagine that a magic fairy comes and creates a system that works  
>>> exactly as you prescribe.
>>>      Now, how will you or your users guess that 64MB RAM / 100MB disk  
>>> / 100MB traffic/day is appropriate for one application, while others  
>>> use different figures?
>>
>> Would you say that the above is any different from a single computer  
>> system with exactly the capacity limits you gave? If so, mind to  
>> explain?
>
> I agree that they're the same. And I would never order a computer saying  
> that it must not have more than 64MB, 100MB disk, nor allow more than  
> 100MB traffic/day. Nor would I attempt to implement "safety" that way on  
> a single or partitioned computer.

Then, how would you "implement" it?

>> BTW: in ancient (computer age) times we had to implement contingency  
>> systems (sometimes mistakenly called accounting systems) because there  
>> was only one computer for 1,000's of users, like for example here:
>
> Indeed, and there is good reason that computers are no longer  
> implemented that way.

I don't believe that. Do you mean that you can upload your malicious code  
to one of the grids

- http://en.wikipedia.org/wiki/Grid_computing

and it (the grid) will immediately allocate all its resources and all its  
processing power that your code asks for?

Indeed, there *are* good reasons that computer (systems) *are* implemented  
that way (regardless of the # of CPU's etc). And the grid is not an  
exception: every OS constrains *all* available resources, one way or the  
other, even its own resources. There is no way out.

The question in the original post was, how to do that with Squeak (cross  
platform, of course!).

> While I certainly don't feel that "no body does it that way" is a valid  
> argument that something should not be done, I do feel it is instructive  
> to note that, while there are many projects to build distributed systems  
> that allow resources to be shared among computers, the opposite does not  
> appear to be true (e.g., hardware systems that segregate or cap  
> resources).

But the physical "hard" limits of computer systems are indistinguishable  
 from "soft" (administrated) limits. There is no difference observable by  
any piece of software of any kind.

> It's rather suspect that the original project spec of how to limit  
> resource use on a single processor

My example below was about a *single computer system* with multiple CPUs  
and tons of time-shared terminals for use by the students.

> should come out of a problem in distributed computing, which by  
> definition is an attempt to gain overall system power and access by  
> sharing resources between computers. There's a good heuristic: Don't  
> create a feature requirement that contravenes the overriding project  
> goal!

The project goal is that no student can crash the university's computer  
system(s) and also can not dominate available resources. Every student  
must be given the compiler, disk space, etc, in order that they can work  
and can produce their malicious code (by chance or by using their free  
will). This is the (typical) situation when you give Squeak to a user  
(regardless of the institution and of the application).

>>
>> - http://www.unibw.de/
>>
>> on a B7800/B7900, the successor of the B5000.
>>
> Thanks for making my point!

NP.

/Klaus


Reply | Threaded
Open this post in threaded view
|

Re: Puzzle: Adding domain-based security to Squeak.

David T. Lewis
In reply to this post by Michael Roberts-2
On Tue, Aug 08, 2006 at 09:29:00PM +0100, Michael Roberts wrote:

>
> On 8 Aug 2006, at 10:03, Michael van der Gulik wrote:
>
> >Hi Howard.
> >
> >I forgot to mention that the reason I'm doing this is to allow  
> >untrusted foreign code to run in the same image as trusted code.  
> >Untrusted code must be carefully managed - it must not be able to  
> >consume large amounts of memory, CPU or disk space to which it is  
> >not entitled. Untrusted code / objects must not prevent trusted  
> >code from operating well.
>
> This is not exactly what you asked for, but -
>
> as an experiment why not run your untrusted code in a separate  
> image?  If you were running this on unix then you could limit the  
> memory given to this separate image - either via say ulimit in the  
> shell or something fancier (maybe via the os process plugin).  You  
> could then talk to the 'jail' image via remote messaging.  It  
> wouldn't take very long to knock up and it might give you interesting  
> results early.

An easy way to do start the remote images is UnixProcess class>>forkSqueakAndDo:,
but you'll want to do something to make sure the remote images are not
writing to their original changes file, otherwise you'll have a swarm
of images all scribbling on the same changes file.

If the remote images are short-lived and do not do things that result
in a lot of garbage collection, then the overall memory usage is
surprisingly light. I presume that this would do reasonable things
on a multiprocessor system also, although I don't have a system to
try it on.

Dave


Reply | Threaded
Open this post in threaded view
|

Re: Puzzle: Adding domain-based security to Squeak.

Howard Stearns
In reply to this post by Klaus D. Witzel


Klaus D. Witzel wrote:

> On Tue, 08 Aug 2006 18:04:07 +0200, Howard Stearns wrote:
>> Klaus D. Witzel wrote:
>>> On Tue, 08 Aug 2006 16:53:46 +0200, Howard Stearns wrote:
>>>
>>>> Imagine that a magic fairy comes and creates a system that works
>>>> exactly as you prescribe.
>>>>      Now, how will you or your users guess that 64MB RAM / 100MB
>>>> disk / 100MB traffic/day is appropriate for one application, while
>>>> others use different figures?
>>>
>>> Would you say that the above is any different from a single computer
>>> system with exactly the capacity limits you gave? If so, mind to
>>> explain?
>>
>> I agree that they're the same. And I would never order a computer
>> saying that it must not have more than 64MB, 100MB disk, nor allow
>> more than 100MB traffic/day. Nor would I attempt to implement
>> "safety" that way on a single or partitioned computer.
>
> Then, how would you "implement" it?

Rats, I thought I answered that in my first message on this thread. ;-)

I don't know of a silver bullet to implementing safety. No one thing
with a catchy name that has been articulated as a necessary and
sufficient strategy.  Sandboxes and Access Control Lists have already
been shown to be neither necessary nor sufficient.  (And to me,
Michael's original formulation of "Domains" are just ACLs by another
name.) Through the thread, I and others have mentioned some principles
that I do feel are helpful enough to be significant (if not necessarily
"solving" the problem). These include defense-in-depth, end-to-end,
capabilities, and the thing I mentioned in my first message, which I
don't have a name for, in which you make the user pick a resource when
you really need one so that the user knows what's happening, rather than
just barring access altogether.

In addition to using the above to figure out what behavior should be
controlled and how to manage that control, there's still the issue of
enforcing that control. I suspect that in a class-based system, this is
precisely equivalent to versioned classes: you want to ensure that an
instance is using a version of a class that implements the behavior
safely, and dynamic changes to the class create new versions. I think
there are only two strategies for versioning classes: either you include
the class with the mobile code, or you have a form of linking in which
you specify (in a secure way) what "version" of the class is required.  
Both Andreas and Craig are working in this area. (For my part, my faith
in the religion of classes has been shaken over the last year and a
half, and I'm toying with converting to prototype/delegationism. This
makes it easier for different objects in the same application to
implement versions of behaviors. But I don't know yet how this all fits
together with enforcing, e.g., capabilities.)

>
>>> BTW: in ancient (computer age) times we had to implement contingency
>>> systems (sometimes mistakenly called accounting systems) because
>>> there was only one computer for 1,000's of users, like for example
>>> here:
>>
>> Indeed, and there is good reason that computers are no longer
>> implemented that way.
>
> I don't believe that. Do you mean that you can upload your malicious
> code to one of the grids
>
> - http://en.wikipedia.org/wiki/Grid_computing
>
> and it (the grid) will immediately allocate all its resources and all
> its processing power that your code asks for?
>
> Indeed, there *are* good reasons that computer (systems) *are*
> implemented that way (regardless of the # of CPU's etc). And the grid
> is not an exception: every OS constrains *all* available resources,
> one way or the other, even its own resources. There is no way out.
>
> The question in the original post was, how to do that with Squeak
> (cross platform, of course!).
No. It is easy to confuse a goal with an implementation, and I think
that's what's happening here.

Klaus, what you and Danil are quite rightly describing is the the goal
of assuring that you have the resources to do your work.
Michael's original post is about a particular technique (essentially,
implementing ACLs for objects/processes/islands/whatever to bind them to
a particular sandbox). While this technique is an interesting puzzle
(the part I like about the subject line of the original message), it is
not, IMHO, a good strategy for providing the goal of a meaningful,
practical measure of security in a mobile code system (the part that I
and others have not liked about the subject line of the original message).

 I think (?) that most of the large scale grid system, including Seti
and my university's own Condor, take a trivial approach to "level of
service": they DO take over the whole processor, but only when there's
no keyboard/mouse activity for a long enough time. They checkpoint
periodically, and lose all their work since the last checkpoint when you
interrupt it by typing again. It's really all quite crude.

Ensuring "enough resources" is a "hard problem." ("Here's a Turing
machine," said the professor to the student. "Please make sure there's
enough tape in it to run this program. But don't run the program
first.")  I think it's pretty clear that I feel that asking users to
pick limits (configure the tape) isn't going to get you anywhere.

>
>> While I certainly don't feel that "no body does it that way" is a
>> valid argument that something should not be done, I do feel it is
>> instructive to note that, while there are many projects to build
>> distributed systems that allow resources to be shared among
>> computers, the opposite does not appear to be true (e.g., hardware
>> systems that segregate or cap resources).
>
> But the physical "hard" limits of computer systems are
> indistinguishable from "soft" (administrated) limits. There is no
> difference observable by any piece of software of any kind.
>
>> It's rather suspect that the original project spec of how to limit
>> resource use on a single processor
>
> My example below was about a *single computer system* with multiple
> CPUs and tons of time-shared terminals for use by the students.
>
>> should come out of a problem in distributed computing, which by
>> definition is an attempt to gain overall system power and access by
>> sharing resources between computers. There's a good heuristic: Don't
>> create a feature requirement that contravenes the overriding project
>> goal!
>
> The project goal is that no student can crash the university's
> computer system(s) and also can not dominate available resources.
> Every student must be given the compiler, disk space, etc, in order
> that they can work and can produce their malicious code (by chance or
> by using their free will). This is the (typical) situation when you
> give Squeak to a user (regardless of the institution and of the
> application).
>
>>>
>>> - http://www.unibw.de/
>>>
>>> on a B7800/B7900, the successor of the B5000.
>>>
>> Thanks for making my point!
>
> NP.
>
> /Klaus
>
>

--
Howard Stearns
University of Wisconsin - Madison
Division of Information Technology
mailto:[hidden email]
jabber:[hidden email]
voice:+1-608-262-3724


Reply | Threaded
Open this post in threaded view
|

Re: Puzzle: Adding domain-based security to Squeak.

Klaus D. Witzel
On Wed, 09 Aug 2006 15:57:58 +0200, Howard Stearns wrote:
...cut away many interesting details...
> (For my part, my faith in the religion of classes has been shaken over  
> the last year and a half, and I'm toying with converting to  
> prototype/delegationism.

Hhm, same toy that I have here for about a year and a half or so ;-) But  
there is a way for class religion and prototype/delegationism to coexist  
(compiler already works here, in Squeak). Further to self includes:  
Smalltalk, Smalltalk includes: self :)

> This makes it easier for different objects in the same application to  
> implement versions of behaviors. But I don't know yet how this all fits  
> together with enforcing, e.g., capabilities.)

Yes, problem class does not change, because of the aforementioned mutual  
implication.

...
> Ensuring "enough resources" is a "hard problem." ("Here's a Turing  
> machine," said the professor to the student. "Please make sure there's  
> enough tape in it to run this program. But don't run the program first.")

No problem if that problem where in NP-complete. But it apparently isn't,  
for example it can be reduced to Turing's halting problem.

> I think it's pretty clear that I feel that asking users to pick limits  
> (configure the tape) isn't going to get you anywhere.
...hhm, and I thought that:
>> But the physical "hard" limits of computer systems are  
>> indistinguishable from "soft" (administrated) limits. There is no  
>> difference observable by any piece of software of any kind.

Howard, this was an interesting discussion. Take care with the  
capabilities (they are fragile) and may you never run out of Turing tape  
8-)

/Klaus


Reply | Threaded
Open this post in threaded view
|

Re: Puzzle: Adding domain-based security to Squeak.

Michael van der Gulik
In reply to this post by Andreas.Raab
Major modifications to the VM? Good grief.

I was thinking that you could re-write new or basicNew or equivalent
entry point to increment a domain's memory counter. If that memory
counter goes over a limit, then new or basicNew would wait on a
Semaphore until the limit has gone under again. Or it could throw an
Exception or something.

Then I believe >>finalize is the method called when the GC happens. This
would do the opposite.

I'll be putting my code where my mouth is soon and see if this would work.

Oh, and the references all look useful. I really need to get looking at
Islands properly; I believe it solves a few other problems I'm working
around.

Michael.

Andreas Raab wrote:

> None of the cited references will solve the original problem(s). They
> are related but they won't solve it. Managing memory limits alone would
> require *major* modifications of the VM.
>
> Cheers,
>   - Andreas
>
> Frank Shearar wrote:
>
>> "Michael van der Gulik" <[hidden email]> wrote:
>>
>>> Hi Howard.
>>>
>>> I forgot to mention that the reason I'm doing this is to allow untrusted
>>> foreign code to run in the same image as trusted code. Untrusted code
>>> must be carefully managed - it must not be able to consume large amounts
>>> of memory, CPU or disk space to which it is not entitled. Untrusted code
>>> / objects must not prevent trusted code from operating well.
>>
>>
>> Have you looked at the (Tweak) Islands [1] work? Lex Spoon also did work
>> with the same name [2], IIRC. And there's the Squeak-E [3] stuff too.
>>
>> [1] http://tweak.impara.de/TECHNOLOGY/Whitepapers/Islands/
>> [2] http://minnow.cc.gatech.edu/squeak/2074
>> [3] http://www.erights.org/history/squeak-e.html
>>
>> frank
>>
>>
>>
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Puzzle: Adding domain-based security to Squeak.

Michael van der Gulik
In reply to this post by David T. Lewis
David T. Lewis wrote:

> On Tue, Aug 08, 2006 at 09:29:00PM +0100, Michael Roberts wrote:
>
>>On 8 Aug 2006, at 10:03, Michael van der Gulik wrote:
>>
>>
>>>Hi Howard.
>>>
>>>I forgot to mention that the reason I'm doing this is to allow  
>>>untrusted foreign code to run in the same image as trusted code.  
>>>Untrusted code must be carefully managed - it must not be able to  
>>>consume large amounts of memory, CPU or disk space to which it is  
>>>not entitled. Untrusted code / objects must not prevent trusted  
>>>code from operating well.
>>
>>This is not exactly what you asked for, but -
>>
>>as an experiment why not run your untrusted code in a separate  
>>image?  If you were running this on unix then you could limit the  
>>memory given to this separate image - either via say ulimit in the  
>>shell or something fancier (maybe via the os process plugin).  You  
>>could then talk to the 'jail' image via remote messaging.  It  
>>wouldn't take very long to knock up and it might give you interesting  
>>results early.

That idea actually has potential. I'll ponder on it. Some methods of
keeping it OS independant would need to be thought about.

Hmm. It would mean that objects in separate domains couldn't reference
each other.

> An easy way to do start the remote images is UnixProcess class>>forkSqueakAndDo:,
> but you'll want to do something to make sure the remote images are not
> writing to their original changes file, otherwise you'll have a swarm
> of images all scribbling on the same changes file.

Yea; I've been hit with that problem already. Damn near lost my code. I
should record that as a bug in Squeak - the changes file needs a lock
system on it so that only one Squeak instance writes to it.

In fact, I've gotten to the stage of saving everything to Monticello
after every small change, and then restarting the image after I run it
(the code I have so far completely frobs the image beyond repair...).

Michael.


Reply | Threaded
Open this post in threaded view
|

Domaining using classes.

Michael van der Gulik
In reply to this post by Klaus D. Witzel
Klaus D. Witzel wrote:
> Hi Michael,
>
> on Tue, 08 Aug 2006 11:19:37 +0200, you wrote:
>
> Klaus D. Witzel wrote:
> That's the easy part: clones of classes share their method dictionary
> (in  form of a pointer, not as a copy). Only the class pointer of per
> domain  created instances is changed, nothing more and nothing else. A
> very good  ROI, that is :)

....wow. That is thinking outside the square. I had never considered
stripping a thin layer off Class/Metaclass like that.

So, a concrete example is needed. Say I have a class "Person". Then,
normally:

alice := Person new.
bob := Person new.

In a domained image, say I have two domains, alicesDomain ("ad") and
bobsDomain ("bd"). Now:

adPerson = Person class copy new. " adPerson is a Class "
"<<Do class initialisation and stuff here, copying stuff from Person>>"
adPerson methodDict: Person methodDict.
adPerson domain: alicesDomain. " Sets an instance variable in the Class"

bdPerson = Person class copy new.
"<<Do class initialisation here>>"
bdPerson methodDict: Person methodDict.
bdPerson domain: bobsDomain.

Now we can do:
alice := adPerson new.
bob := bdPerson new.

In other words, each domain has its own set of classes, but each class
shares its instance variables (methodDict, instanceVariables,
superclass, format etc) with other classes of the same... er... class.

I could probably cludge up some Namespacing or other magic to get
"Person" to resolve to the domain's local version of the Person class,
so you don't need to use "adPerson" and "bdPerson" but just "Person".

So now, finding the domain of any given object would be easy:

Object>>domain
        ^ self class domain.

Trivial!

The code below hasn't been properly thought out wrt security etc, but
looks good in theory :-). I'll probably break a few images trying to get
it working as well.

Object>>new
        self domain waitUntilCanMakeMoreObjects.
        ^ self basicNew initialize.

Domain>>waitUntilCanMakeMoreObjects
        objectCounter := objectCounter + 1.
        (objectCounter > maxObjects) ifTrue:
                [ tooManyObjectsSemaphore wait ].

Object>>finalize
        " This may or may not work... I haven't used >>finalize before"
        self domain freeOneObject.

Domain>>freeOneObject
        objectCounter := objectCounter - 1.
        ( do bug-free magic ) ifTrue: [ tooManyObjectsSemaphore signal ].

And ditto for Processes :-).

Advantages:
- should hopefully be more efficient than adding an instance variable
("domain") to Object.
- Can also do Class>>allInstances to count up object memory usage in a
domain.
- Can also do this with special objects like SmallInteger, Array,
CompiledMethod, ...
- Also has nice side-effects, e.g. pools, class variables, class-side
instance variables, Environments/Namespaces/SystemDictionaries can be
domain specific.

Disadvantages:
- umm... well its a bit hard to implement, but no less so than any other
ways of doing this.

So who takes the credit for this? Alexandre Bergel and Klaus Witzel?

Michael.


Reply | Threaded
Open this post in threaded view
|

Re: Domaining using classes.

Klaus D. Witzel
On Sat, 12 Aug 2006 03:41:17 +0200, Michael van der Gulik wrote:

> Klaus D. Witzel wrote:
>> Hi Michael,
>>  on Tue, 08 Aug 2006 11:19:37 +0200, you wrote:
>>  Klaus D. Witzel wrote:
>> That's the easy part: clones of classes share their method dictionary  
>> (in  form of a pointer, not as a copy). Only the class pointer of per  
>> domain  created instances is changed, nothing more and nothing else. A  
>> very good  ROI, that is :)
>
> ....wow. That is thinking outside the square. I had never considered  
> stripping a thin layer off Class/Metaclass like that.
>
> So, a concrete example is needed. Say I have a class "Person". Then,  
> normally:
>
> alice := Person new.
> bob := Person new.
>
> In a domained image, say I have two domains, alicesDomain ("ad") and  
> bobsDomain ("bd"). Now:
>
> adPerson = Person class copy new. " adPerson is a Class "
> "<<Do class initialisation and stuff here, copying stuff from Person>>"
> adPerson methodDict: Person methodDict.
> adPerson domain: alicesDomain. " Sets an instance variable in the Class"
>
> bdPerson = Person class copy new.
> "<<Do class initialisation here>>"
> bdPerson methodDict: Person methodDict.
> bdPerson domain: bobsDomain.
Take care when uttering #copy in the presence of a class (e.g. a behavior)  
and/or #new in the presence of a metaclass. I would'nt even whisper such  
words when a class is around; classes/behavior have (too) tight a relation  
with ClassBuilder and comrades, so I tend to think of it as #copy being  
reserved for exclusive use by that comradeship.

I always use #clone for classes (after checking with the implementors of  
#clone in the releases of Squeak, of course).

> Now we can do:
> alice := adPerson new.
> bob := bdPerson new.

   8-)

> In other words, each domain has its own set of classes, but each class  
> shares its instance variables (methodDict, instanceVariables,  
> superclass, format etc) with other classes of the same... er... class.

Yes, and it would be sufficient to just clone the fields superclass,  
methodDict and format (like in an instance of Behavior). This is all that  
the VM needs. I have direct subclasses of Behavior in my projects, see  
attached example on negotiable interfaces. Message category  
'*required-by-my-users' keeps users of direct subclasses of Behavior not  
bark so loud.

> I could probably cludge up some Namespacing or other magic to get  
> "Person" to resolve to the domain's local version of the Person class,  
> so you don't need to use "adPerson" and "bdPerson" but just "Person".
>
> So now, finding the domain of any given object would be easy:
>
> Object>>domain
> ^ self class domain.
>
> Trivial!
   ;)

> Disadvantages:
> - umm... well its a bit hard to implement, but no less so than any other  
> ways of doing this.

Yes, I think so, too.

> So who takes the credit for this? Alexandre Bergel and Klaus Witzel?

Alex was the first person that I met who understood what I was talking  
about. So yes, it was invented by the two of us.

/Klaus

> Michael.


NegotiableInterface.st (22K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Domaining using classes.

Klaus D. Witzel
In reply to this post by Michael van der Gulik
On Sat, 12 Aug 2006 03:41:17 +0200, Michael van der Gulik wrote:
...
> In other words, each domain has its own set of classes, but each class  
> shares its instance variables (methodDict, instanceVariables,  
> superclass, format etc) with other classes of the same... er... class.
>
> I could probably cludge up some Namespacing or other magic to get  
> "Person" to resolve to the domain's local version of the Person class,  
> so you don't need to use "adPerson" and "bdPerson" but just "Person".

Have you considered using classboxes for that, see

- http://citeseer.ist.psu.edu/684648.html

Though classboxes is about local methods, it can be put to use for "just"  
local classes.

/Klaus


Reply | Threaded
Open this post in threaded view
|

Re: Domaining using classes.

stéphane ducasse-2
But classboxes were an experiment. The tool support is not deep enough


On 12 août 06, at 05:45, Klaus D. Witzel wrote:

> On Sat, 12 Aug 2006 03:41:17 +0200, Michael van der Gulik wrote:
> ...
>> In other words, each domain has its own set of classes, but each  
>> class shares its instance variables (methodDict,  
>> instanceVariables, superclass, format etc) with other classes of  
>> the same... er... class.
>>
>> I could probably cludge up some Namespacing or other magic to get  
>> "Person" to resolve to the domain's local version of the Person  
>> class, so you don't need to use "adPerson" and "bdPerson" but just  
>> "Person".
>
> Have you considered using classboxes for that, see
>
> - http://citeseer.ist.psu.edu/684648.html
>
> Though classboxes is about local methods, it can be put to use for  
> "just" local classes.
>
> /Klaus
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Domaining using classes.

Klaus D. Witzel
On Sat, 12 Aug 2006 10:50:56 +0200, stéphane ducasse wrote:

> But classboxes were an experiment. The tool support is not deep enough

Thanks for the hint, Stef.

Nevertheless, I'd say it is worth the investigation, just to find out what  
can be stolen from others (err, reused).

And tool support is not an issue here, just "clones of local classes on  
the fly", which become garbage after an app (or a client or so) is closed.

/Klaus


Reply | Threaded
Open this post in threaded view
|

Re: Domaining using classes.

Klaus D. Witzel
In reply to this post by Klaus D. Witzel
On Thu, 24 Aug 2006 09:46:18 +0200, Alexandre Bergel wrote:

> Sorry to answer so late, I got few emergencies in my work.

So we have to thank you twice for your response :)

> The technique you describes, Classboxes and selector namespace are  
> similar somehow. They provide way to (i) support changes in an  
> unanticipated ways and to (ii) obtain a better modularity of cross-
> cutting concern. Note that these techniques are not alone, family  
> polymorphism (i.e., the gbeta programming language), virtual classes  
> (i.e., caesarJ), mixin-based inheritance (i.e., Units in MZScheme) help  
> in achieving similar goals.
>
> The differences between those systems reside in some very subtle detail  
> in their semantics. In your example, what happens if a a method in the  
> "bd" domain calls a method foo in the "ad" domain. Now ad.foo call bar,  
> which is defined in both domain.

In domaining using classes, this is exactly what is wanted, all behavior  
(=methodDict's) is shared at the oop level, no copy hangs around :)

> Which one get invoked ?

Domain a and domain b have precisely the same superclass (oop). So the  
answer is: always the right one, since there exists only one implementor.

/Klaus

> Depending on the answer, you have the behavior of Classboxes or selector  
> namespace. If you want more about those difference, I can point out a  
> paper we wrote on it.
>
> Regards,
> Alexandre
>
>
> Am Aug 12, 2006 um 4:45 AM schrieb Klaus D. Witzel:
>
>> On Sat, 12 Aug 2006 03:41:17 +0200, Michael van der Gulik wrote:
>> ...
>>> In other words, each domain has its own set of classes, but each class  
>>> shares its instance variables (methodDict, instanceVariables,  
>>> superclass, format etc) with other classes of the same... er... class.
>>>
>>> I could probably cludge up some Namespacing or other magic to get  
>>> "Person" to resolve to the domain's local version of the Person class,  
>>> so you don't need to use "adPerson" and "bdPerson" but just "Person".
>>
>> Have you considered using classboxes for that, see
>>
>> - http://citeseer.ist.psu.edu/684648.html
>>
>> Though classboxes is about local methods, it can be put to use for  
>> "just" local classes.
>>
>> /Klaus
>>
>



Reply | Threaded
Open this post in threaded view
|

Re: Domaining using classes.

Klaus D. Witzel
Hi Alex,

can we keep this discussion thread in squeak-dev (and if so then please  
don't reply just to me).

On Thu, 24 Aug 2006 10:55:40 +0200, Alexandre Bergel wrote:

>> Domain a and domain b have precisely the same superclass (oop). So the  
>> answer is: always the right one, since there exists only one  
>> implementor.
>
> It means that a client is always in one (and only one) domain. How those  
> domains are composed each other ?
>
> For instance, a short example of a class Person that has two domains:  
> employee and student.

Initially, "domaining using classes" has only a Person class. This class  
(and all other classes in the same image) belong to the single #system  
domain by default.

When an #employee domain or #student domain is created, instances of  
Person become member of the respective domain as follows:

  employeePerson := (Person clone nowYouClonedClassBelongsToDomain:  
#employee) new.
  studentPerson := (Person clone nowYouClonedClassBelongsToDomain:  
#student) new.

Observe when and where #new is executed. Then,

  (employeePerson domain) printIt => #employee
  (studentPerson domain) printIt => #student

  (employeePerson class) printIt => 'a Person in domain #employee'
  (studentPerson class) printIt => 'a Person in domain #student'

> Person>>employeeDomain.salary
> ^ 2000
>
> Person>>studentDomain.nbOfCoursesTaken
> ^ 4
>
> Easy.

I think that our subject "domaining using classes" does not have such  
methods. The methods do not change when domain membership becomes  
effective (i.e. do not have the domainName. prefix from your examples),  
they change neither automagically nor manually.

> the method salary can be invoked by an object x only if x "is" in a  
> domain employee. Same thing for nbOfCourseTaken.
>
> Imagine now the few methods:
>
> "Public methods"
> Person>>employeeDomain.printString
> ^ self printOn: (WriteStream on: String new).
>
> Person>>studentDomain.printString
> ^ self printOn: (WriteStream on: String new).
>
>
> Person>>printOn: stream
> self generalInfo printOn: steram "CRITICAL QUESTION HERE"
> self description printOn: stream "CRITICAL QUESTION HERE"
>
> Person>>employeeDomain.description
> "Description for being an employee"

An instance of Person in domain #employee does not have the "is an  
employeePerson" property. Instead, it has the "my class belongs to the  
#employee domain" property. This implies that the "domained" Person  
instance belong the their class' domain.

> Person>>employeeDomain. generalInfo
> "Description for being an employee"

Same as above.

> Person>>studentDomain.description
> "Description for being a student"

Same as above with s/employee/student/.

> Person>>studentDomain. generalInfo
> "Description for being a student"

Same as above with s/employee/student/.

> printOn: is not part of any domain (or belongs to a 'default' domain).  
> When printOn: is invoked, how do you know the right method to select ?

Since we have "just" clones of classes, we always select the right method,  
because only that one method exists?

> What does it mean to "be" in a domain ?

Any class can be cloned and the clone is added to a domain (a domain has  
an identifier and a collection of members, i.e. a collection of cloned  
classes). Instances of a domained class belong to their class' domain.

> I am really interested by this discussion!

:)

/Klaus

> cheers,
> Alexandre


Reply | Threaded
Open this post in threaded view
|

Re: Domaining using classes.

Alexandre Bergel-2
> Initially, "domaining using classes" has only a Person class. This  
> class (and all other classes in the same image) belong to the  
> single #system domain by default.
>
> When an #employee domain or #student domain is created, instances  
> of Person become member of the respective domain as follows:
>
>  employeePerson := (Person clone nowYouClonedClassBelongsToDomain:  
> #employee) new.
>  studentPerson := (Person clone nowYouClonedClassBelongsToDomain:  
> #student) new.
>
> Observe when and where #new is executed. Then,
>
>  (employeePerson domain) printIt => #employee
>  (studentPerson domain) printIt => #student

What is the difference between this and a classical namespace ?

With namespaces I would have:
employeePerson := Employee.Person new.
studentPerson := Student.Person new.

(employeePerson class namespace) printIt => #employee
(studentPerson class namespace) printIt => #student


What is the impact of domaining on the method lookup ?

cheers,
Alexandre



Am Aug 24, 2006 um 10:57 AM schrieb Klaus D. Witzel:

> Hi Alex,
>
> can we keep this discussion thread in squeak-dev (and if so then  
> please don't reply just to me).
>
> On Thu, 24 Aug 2006 10:55:40 +0200, Alexandre Bergel wrote:
>
>>> Domain a and domain b have precisely the same superclass (oop).  
>>> So the answer is: always the right one, since there exists only  
>>> one implementor.
>>
>> It means that a client is always in one (and only one) domain. How  
>> those domains are composed each other ?
>>
>> For instance, a short example of a class Person that has two  
>> domains: employee and student.
>
> Initially, "domaining using classes" has only a Person class. This  
> class (and all other classes in the same image) belong to the  
> single #system domain by default.
>
> When an #employee domain or #student domain is created, instances  
> of Person become member of the respective domain as follows:
>
>  employeePerson := (Person clone nowYouClonedClassBelongsToDomain:  
> #employee) new.
>  studentPerson := (Person clone nowYouClonedClassBelongsToDomain:  
> #student) new.
>
> Observe when and where #new is executed. Then,
>
>  (employeePerson domain) printIt => #employee
>  (studentPerson domain) printIt => #student
>
>  (employeePerson class) printIt => 'a Person in domain #employee'
>  (studentPerson class) printIt => 'a Person in domain #student'
>
>> Person>>employeeDomain.salary
>> ^ 2000
>>
>> Person>>studentDomain.nbOfCoursesTaken
>> ^ 4
>>
>> Easy.
>
> I think that our subject "domaining using classes" does not have  
> such methods. The methods do not change when domain membership  
> becomes effective (i.e. do not have the domainName. prefix from  
> your examples), they change neither automagically nor manually.
>
>> the method salary can be invoked by an object x only if x "is" in  
>> a domain employee. Same thing for nbOfCourseTaken.
>>
>> Imagine now the few methods:
>>
>> "Public methods"
>> Person>>employeeDomain.printString
>> ^ self printOn: (WriteStream on: String new).
>>
>> Person>>studentDomain.printString
>> ^ self printOn: (WriteStream on: String new).
>>
>>
>> Person>>printOn: stream
>> self generalInfo printOn: steram "CRITICAL QUESTION HERE"
>> self description printOn: stream "CRITICAL QUESTION HERE"
>>
>> Person>>employeeDomain.description
>> "Description for being an employee"
>
> An instance of Person in domain #employee does not have the "is an  
> employeePerson" property. Instead, it has the "my class belongs to  
> the #employee domain" property. This implies that the "domained"  
> Person instance belong the their class' domain.
>
>> Person>>employeeDomain. generalInfo
>> "Description for being an employee"
>
> Same as above.
>
>> Person>>studentDomain.description
>> "Description for being a student"
>
> Same as above with s/employee/student/.
>
>> Person>>studentDomain. generalInfo
>> "Description for being a student"
>
> Same as above with s/employee/student/.
>
>> printOn: is not part of any domain (or belongs to a 'default'  
>> domain). When printOn: is invoked, how do you know the right  
>> method to select ?
>
> Since we have "just" clones of classes, we always select the right  
> method, because only that one method exists?
>
>> What does it mean to "be" in a domain ?
>
> Any class can be cloned and the clone is added to a domain (a  
> domain has an identifier and a collection of members, i.e. a  
> collection of cloned classes). Instances of a domained class belong  
> to their class' domain.
>
>> I am really interested by this discussion!
>
> :)
>
> /Klaus
>
>> cheers,
>> Alexandre
>

--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.cs.tcd.ie/Alexandre.Bergel
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.




Reply | Threaded
Open this post in threaded view
|

Re: Domaining using classes.

Klaus D. Witzel
On Thu, 24 Aug 2006 16:14:05 +0200, Alexandre Bergel wrote:

> Klaus wrote:
>> Initially, "domaining using classes" has only a Person class. This  
>> class (and all other classes in the same image) belong to the single  
>> #system domain by default.
>>
>> When an #employee domain or #student domain is created, instances of  
>> Person become member of the respective domain as follows:
>>
>>  employeePerson := (Person clone nowYouClonedClassBelongsToDomain:  
>> #employee) new.
>>  studentPerson := (Person clone nowYouClonedClassBelongsToDomain:  
>> #student) new.
>>
>> Observe when and where #new is executed. Then,
>>
>>  (employeePerson domain) printIt => #employee
>>  (studentPerson domain) printIt => #student
>
> What is the difference between this and a classical namespace ?

Several differences are at work here:

- Squeak doesn't have such thing
- same class (#clone) is in multiple name spaces, what other system does  
that?
- Michael van der Gulik, the first potential user, "just" wants to  
partition object memory into domains (by coloring classes, as discussed  
with you in Bern)
- the domained instances have only a "thin" change: just their class  
pointer differs between domains
- behavior is the same in all domains

> With namespaces I would have:
> employeePerson := Employee.Person new.
> studentPerson := Student.Person new.

Nice. In which system (language, programmable) is this fully supported  
(having only one class object named Person)?

> (employeePerson class namespace) printIt => #employee
> (studentPerson class namespace) printIt => #student
>
> What is the impact of domaining on the method lookup ?

At the current stage of discussion: none, but that will change as soon as  
the next idea arrives :)

/Klaus

> cheers,
> Alexandre


Reply | Threaded
Open this post in threaded view
|

Re: Domaining using classes.

Michael van der Gulik
In reply to this post by Alexandre Bergel-2
Alexandre Bergel wrote:

>> Initially, "domaining using classes" has only a Person class. This  
>> class (and all other classes in the same image) belong to the  single
>> #system domain by default.
>>
>> When an #employee domain or #student domain is created, instances  of
>> Person become member of the respective domain as follows:
>>
>>  employeePerson := (Person clone nowYouClonedClassBelongsToDomain:  
>> #employee) new.
>>  studentPerson := (Person clone nowYouClonedClassBelongsToDomain:  
>> #student) new.

Umm... yea... whatever. It depends how its all implemented.

>> Observe when and where #new is executed. Then,
>>
>>  (employeePerson domain) printIt => #employee
>>  (studentPerson domain) printIt => #student
>
>
> What is the difference between this and a classical namespace ?
>
> With namespaces I would have:
> employeePerson := Employee.Person new.
> studentPerson := Student.Person new.

Domains are used for managing resources.

Namespaces are used for managing the uniqueness of class names.

Many objects of the same class (and thus in the same Namespace) could be
in different domains.

The concept of a "Domain" is my own invention, and I'm not entirely
happy with the name; it's already overused in many areas of computer
science. Perhaps "ResourceDomain" would be a better name?

Also; don't get too caught up with implementation details. At the moment
I've got working code which basically copies a class, adds a domain
instance var to that class object and returns a new object of that
class. It works, but it's a big hack and is only excusable because I
couldn't think of a better way of implementing it without massive VM
changes.

Ideally, there would be VM changes which would group objects of the same
domain physically in memory.

I also think a Domain like I'm using it is just like Lex Spoon's
Islands, so I'll be looking at his code soon. Incidentally, it seems
I've implemented one of the few things he didn't - managing memory usage.

Islands: http://minnow.cc.gatech.edu/squeak/2074

> (employeePerson class namespace) printIt => #employee
> (studentPerson class namespace) printIt => #student
>
>
> What is the impact of domaining on the method lookup ?

Hopefully none, but that's dependent on how it is all implemented.

When my code is usable by others, I'll be putting it online somewhere.

Cheers,
Michael.


12