[squeak-dev] Why is ModificationForbidden not an Error?

David T. Lewis lewis at mail.msen.com
Fri Apr 24 22:05:55 UTC 2020


Thanks Ron, I think that I suddenly understand the issue :-)

Dave

On Fri, Apr 24, 2020 at 02:37:52PM -0400, Ron Teitelbaum wrote:
> Hi all,
> 
> I'd like to add some color here.  I worked with Versant for many many
> years.  This problem bites you so hard you need a tourniquet just to
> survive it.
> 
> Imagine looking at your code and trying to understand why something that
> looks so simple is completely wrong!  You spend a huge amount of time
> trying to understand why the code doesn't actually do what it SAYS it will
> do.  How is this possible?  You read and read, you start
> writing things down but no it is impossible. You feel like you must be
> missing something extremely simple or are just losing your mind. Then you
> decide ok I'll take this step by step and validate every message to see
> exactly where it breaks.  You have been looking at this error for over 72
> hours straight because someone is standing over your shoulder waiting to
> ship the product they promised would be available a week ago.
> 
> So you get to a method Integer fortyTwo.  And it returns #(0) instead of
> #(42).  What the hell is that!!!!  The code says ^#(42)!!!!.  You can see
> it right there!!!  Then it hits you.  I've been bit by a literal variable
> change!  You add copy and now everything works just like you expected it
> to.  Now you need to get the trounequat because after you kicked the trash
> can you split your knee on the table.  Then you go to talk to your
> colleague and he falls asleep while you are talking to him and his head
> hits the keyboard.  You ask your boss who looks nearly as bad as the
> comatose colleague what you should do and he says "Save the code!"  So you
> save the code and roll your colleague under the table so nobody steps on
> him.
> 
> This doesn't happen you think??  Well on Versant you couldn't even change
> the method if the database was holding onto the litteral!  Trying to accept
> a method gave you a database error!!!  Oh great fun that was!
> 
> Some people have learned the hard way with litteral blood that copy is
> essential, and for those that haven't you can save them a lot of pain.
> Changing litterals without the copy is always wrong especially if it will
> eventually be stored in a database.  Imagine doing direct manipulation on a
> litteral.  Now try to explain what happened since the code never actually
> changed anything!!! How the hell did that happen!!
> 
> Try it yourself and then imagine my barely open eyes trying in vain to
> understand what happened!
> 
> Integer class >> fortyTwo
>     ^#(42)
> 
> Integer fortyTwo  #(42)
> Integer fortyTwo at: 1 put: 0.
> Integer fortyTwo #(0)
> 
> Go back and look at the method.  Hasn't changed still says ^#(42).  Good
> luck debugging that!
> 
> I hope that adds some color around this issue. Ok back to your regularly
> scheduled program!
> 
> All the best,
> 
> Ron Teitelbaum
> 
> 
> 
> On Fri, Apr 24, 2020 at 1:16 PM Eliot Miranda <eliot.miranda at gmail.com>
> wrote:
> 
> >
> >
> > On Apr 24, 2020, at 9:59 AM, Jakob Reschke <forums.jakob at resfarm.de>
> > wrote:
> >
> > ???
> > Domain and "data storage" layers are intermixed here, hence the trouble
> > with the concept of read-only. If you don't want such a distinction of
> > layers by using different objects in the first place, then I suggest to at
> > least use separate protocols. So yes, use different managers for
> > different kinds of read-onliness. Your domain-specific layer can still
> > delegate to the VM write barrier if that works well. And different
> > applications can still access the same kind/layer of read-onliness, so
> > Eliot's proposal to have one registry for the VM write barrier handling
> > remains valid.
> >
> > I'd say each domain should also have an own exception class in this case.
> > As an implementation detail, it could inherit from the base
> > ModificationForbidden... or hide the concrete class behind an accessor.
> >
> >
> > No.  That is unnecessary.  The issue is to separate intercepting an
> > attempt to write to a read-only object from what happens in response to
> > that attempt.  And that???s what the ManagedObjects/defaultAction mechanism
> > does.  Attempts to write are caught and other objects handle what happens
> > in response.
> >
> > Thinking of this issue in the co text of exception handlers doesn???t make
> > sense.  Writes happen all over the system, and not necessarily within the
> > dynamic extent of some computation.  The exception handler is global.  So
> > one won???t be able to establish exception handlers for all cases.  Instead,
> > the global exception system dispatches a per-object-specific response
> > through ManagedObjects.
> >
> >
> >
> >
> > Marcel Taeumel <marcel.taeumel at hpi.de> schrieb am Fr., 24. Apr. 2020,
> > 12:10:
> >
> >> >  But this means the DB is now occupying the use of the readOnly bit,
> >> not available for other applications or use-cases.
> >>
> >> Hmmm... ManagedObjects could be partitioned among multiple applications.
> >> For example, a game loading some save state could come across some
> >> read-only objects and then choses how to manage those. Another application
> >> could do this as well, not interfering with the first one. Both might be
> >> considered "small DB managers" so to say.
> >>
> >> Of course, that check "myDomainObject isReadOnlyObject" would become
> >> standard procedure for such DBs, wouldn't it?
> >>
> >> Best,
> >> Marcel
> >>
> >> Am 24.04.2020 05:26:56 schrieb Chris Muller <ma.chris.m at gmail.com>:
> >>
> >>> So if the exception is unhandled, then before it raises an
> >>>> UnhandledError it checks an identity dictionary, which maps object to
> >>>> message, and if the read-only object that was the cause of the error is in
> >>>> the dictionary, instead the exception performs the message with the object
> >>>> as an argument.  So a database layer can add the objects it is managing to
> >>>> the map in ModificationForbidden, and mark them as read-only.  Then any and
> >>>> all attempts at modifying these objects will cause the database man ager to
> >>>> be notified.
> >>>>
> >>>  So very simply we can have a pluggable solution that allows different
> >>>> clients to map the exception into different responses as desired.
> >>>>
> >>>
> >>> But an object in your db table could easily be an Array literal held by
> >>> a CompiledMethod, not expected to change, but persistent by reference
> >>> nonetheless.  So if the application did then modify it accidentally,
> >>> instead of Forbidden protection, your DB manager would happily modify it.
> >>> It's this separation of use-cases is all what the question was about I
> >>> think, not a big deal, we've lived with unprotected CM literals for this
> >>> long already, and I've never needed WriteBarrier for anything other than a
> >>> DB.
> >>>
> >>>
> >>> Since objects get added to the collection intentionally the array
> >>> literal would not be added and hence the manager would not modify it.
> >>>
> >>
> >> How would the manager know not to add it?  It can't be by checking
> >> #isReadOnlyObject, since that presents the same paradox -- requiring the
> >> manager to know the business of whatever other use-case has it set.  If it
> >> assumed it was for CM-literal protection, it wouldn't add it, but what if
> >> it was just some debugging or something?
> >>
> >>
> >>> Your example is a straw man.
> >>>
> >>
> >>>
> >>> However, I still don't see the path for how to use this in a complex
> >>> multi-db Magma application with oblivious objects (e.g., Morphs).  It's not
> >>> something any of the GemStone clients I consulted at as developer or DBA
> >>> ever had to contend with either, but perhaps not something you're
> >>> targeting.  Squeak is a different animal...  I will stay tuned here and
> >>> watch for the answers as they unfold...
> >>>
> >>>
> >>> The objects that get added to the wrote barrier management collection
> >>> get added by managers that want to manage specific objects, not arbitrary
> >>> objects. Can you see that a DB manager would add objects it has
> >>> materialized from the DB that it wanted to transparently write-back in
> >>> modification, and no others?
> >>>
> >>
> >> Yes, absolutely.  The manager will get every ModificationForbidden signal
> >> under its code whether its meant for the DB or not.  Existence in a global
> >> table means handle it, otherwise pass it up the stack.  But this means the
> >> DB is now occupying the use of the readOnly bit, not available for other
> >> applications or use-cases.
> >>
> >> I hope this critique isn't taken to mean I don't think this isn't a good
> >> feature for the VM and image.  I do.  Everything is a balance of features
> >> and limitations.  I'm still trying to determine whether Magma can benefit
> >> from this, and I have to get deeply critical to find the right decision.  I
> >> will be following this feature closely, thanks for your patience with my
> >> questions.
> >>
> >>  - Chris
> >>
> >>
> >>
> >
> >

> 



More information about the Squeak-dev mailing list