Skip to content

Room for Improvement (i.e. issues problems)

Sean DeNigris edited this page Aug 6, 2020 · 5 revisions

TOC

Outstanding Issues

Graphics Mess (Inherited from Squeak)

From the legendary days of Xerox PARC, Alan Kay and Co. have been focused on shortening the typical century-plus that it takes to figure out how to actually utilize new technology (instead of using it to simulate old technology). This naturally puts one on the scale of "Cathedral building" i.e. a project that will not be complete in the lifetime of most of its workers. This creates a natural tension with us poor mere mortals trying to benefits from the scraps which fall from the table. Squeak's Morphic is an example of a system riddled with half-baked experiments that never received a promised cleanup pass and now remains buggy and difficult to understand.

Editor Modification? Woe to thee who attempts!

A classic example of the frustration of dealing with this area is the editor.

OSProcess and OSSubprocess Incompatibility

These two great libraries share functionality in an incompatible way - which is not so great. I first raised this issue in the OSSubprocess release announcement thread. That is probably the most thorough conversation about the problem (and other related ones), as well as the motivation and design of OSSubprocess. I continued to raised this issue whenever the opportunity arose, but as far as I know there are only clues toward solving.

Here I lament about the general problem of libraries which fail to take into account the wider context of existing libraries:

This hints at an issue I've been thinking about a lot lately. It would seem to be a huge boon if frameworks were designed to be more pluggable. The driver of my thoughts were the incompatibility of OSProcess and OSSubprocess, which can't even be loaded at the same time no less plugged in and out! Imagine if we could use Formulas in Seaside, and plug whatever web server into Iliad. It's a shame that each one seems to lock one into an ecosystem - the good with the bad, especially when this kind of stovepiping was one of the very things Smalltalk aimed to avoid! I wonder if there has been any research/experimentation/thinking in this direction…

Potential Solutions (only clues)

[A]s to why [OSSubprocess] breaks when OSProcess is loaded to, it's because for OSSubprocess I took the wonderful idea from OSProcess of the child reaper. This is a process that runs on the Smalltalk side and handles exception (via semaphore) when the child has died. This is (currently) only possible thanks to OSProcess primitive. That means OSSubprocess still needs (one or very little) OSProcess primitives down in the VM. When you load either of the projects, they launch the child reaper process, register the semaphore etc etc. So the problem is when you loaded one and you then try to load the second one, the initialization of the second one you plug its own semaphore etc etc and so the previous gets broken as it doesn't have a working child reaper process.

If someone has a better idea on how to solve this, then please speak up.

The problem is to find a solution that works for both, Squeak and Pharo as well as for OSProcess and OSSubprocess.

I guess one possibility is to modify both, OSProcess and OSSubprocess initialization of the child reaper so that they install the same "generic" child reapear. Aside from initializating the child repear, they should be added into an "observer list". When, when it comes the second project to get loaded it which check that a child reaper is already registered..in which case he just register itself as "observer".

This child reaper should be generic enough (cannot be coupled to WHAT to do when the semaphore is signaled). Using Announcements (or other mechanisim that would work for Pharo and Squeak) we could simply "notify" the registered observers and each observer would do whatever is needed (what is actually now hardcoded in each child reaper)

Maybe that works...just an idea.

[Followup from Dave Lewis]

I cannot follow up for a few days but I like Mariano's proposal and I think that it will work. Maybe move the child reaper process to a small OSChildWatcher class and have interested clients (OSP, OSSP, others) subscribe to update notifications.

I saw Sean's earlier email (see below) which reminded me of your ideas about having a child process listener that could provide child exit notifications to both OSSubprocess and OSProcess. This seems to me to be the right thing to do, but it would take some work by somebody (not by me, but it could be done).

Meanwhile, prompted by Sean's , I think maybe I see another way that we could handle the problem, at least in the near term. I think I see another way that this can be handled for an image that contains both OSSubprocess and OSProcess. I loaded both into a Pharo 7 image, then added this:

OSSVMProcess>>update: aParameter 
        "If subscribed to events from the OSProcess child watcher, the 
        changed/update: mechanism will dispatch child exit notification 
        here. To subscribe to notification from OSProcess add the singleton 
        OSSVMProcess as a dependent of the OSProcess accessor singleton. 
        When any child process exits, this method will be called with 
        parameter #childProcessStatus" 
        
        "OSProcess accessor addDependent: OSSVMProcess vmProcess" 

        (aParameter == #childProcessStatus) ifTrue: 
                [^ self updateActiveChildrenAndNotifyDead]. 

I stopped the child watcher in OSSVMProcess (by commenting out the last two lines in OSSVMProcess>>initialize just to see if this would work), then added the changed/update: dependency with "OSProcess accessor addDependent: OSSVMProcess vmProcess"

After restarting the image, it appears to be working, at least so far has having both OSP and OSSP handle their child process exits properly in the same image.

I don't have time to play with this any more right now, but it does look like it might be a workable approach. It should be possible to have the initializer for OSSVMProcess use its normal child exit handler, but hook into the OSP handler instead if that happens to be present in the image.

I had a good two years run of luck since OSSubprocess was released when I never ran into the intractable (but inevitable) of having a project depending on both OSProcess and OSSubprocess via two project dependencies that each depend on one.

Time Zone Fiasco

There is a very annoying gotcha which comes up from time to time on the MLs. The offset of a DateAndTime et al is computed based on the current offset of the locale of the image. While this might not seem like too big of a deal at first glance, the problem is DST. Consider this thought experiment: at 11:59pm before DST changes, eval aDate := '1/1/1901' asDate. Now, wait two minutes and at 12:01am eval self assert: '1/1/1901' asDate = aDate and… whammo, an exception! The "different" offsets render equal dates unequal depending on when the objects were created. The fact that the offset is the one active at object creation is the key error, because it should be the offset active when the date occurred.

Ideal Solutions

  • Lookup Offset from an authoritative source, like the iana DB on object's date, not today's
  • Reify Timezone, Not Offset; Then you could resolve the proper offset later, but would still need a resource like above. This would at least fix the comparison problem because TZ1 would equal TZ2.

Complications

  • LocalTimeZone's offset is hardcoded in practice because it it calculated in a primitive
  • DateAndTime class>>#localOffset: is set at every image startup and there's no way to disable it other than removing Locale from the startup list

Workarounds

Magritte

If you've used the wonderful Magritte library to describe your objects, you can convert dates to UTC with the following:

"Cache description building, which can be slooooow"
dateDescs := aCollection first magritteDescription select: [ :e | e isKindOf: MADateAndTimeDescription ].
aCollection do: [ :e |
	dateDescs do: [ :d |
		(d read: e) ifNotNil: [ :val | e write: val translateToUTC using: d ] ] ].

Other

  • Setting timezone to UTC: You can't just set the timezone to UTC, because then e.g. DateAndTime now will be off by offset hours. Apparently the primitive already takes the offset into account.

References

Libraries to Research

Bug Reports

  1. https://stackoverflow.com/questions/2532729/daylight-saving-time-and-time-zone-best-practices

Fixed Issues

Iceberg - Absolute Repo Paths

This seems to have been fixed in Iceberg 1.6 (Pharo 8 I think?). See the Pharo issue about this) for more exact details. For older images, in the DeNigrisPreferences project, see DeNigrisPreferences >> #fixIcebergRepoLocations for a script you can adapt.