{"id":15107645,"url":"https://github.com/pharo-ide/seamless","last_synced_at":"2025-10-23T02:31:24.347Z","repository":{"id":48479474,"uuid":"97118498","full_name":"pharo-ide/Seamless","owner":"pharo-ide","description":"Distributed object network for Pharo","archived":false,"fork":false,"pushed_at":"2024-03-29T22:35:55.000Z","size":426,"stargazers_count":21,"open_issues_count":6,"forks_count":12,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-10-09T13:21:29.088Z","etag":null,"topics":["distributed-object","network","pharo","seamless"],"latest_commit_sha":null,"homepage":"http://dionisiydk.blogspot.fr/2016/07/major-seamless-update.html","language":"Smalltalk","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pharo-ide.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-13T12:07:32.000Z","updated_at":"2023-03-21T17:24:15.000Z","dependencies_parsed_at":"2024-09-25T21:40:48.852Z","dependency_job_id":null,"html_url":"https://github.com/pharo-ide/Seamless","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharo-ide%2FSeamless","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharo-ide%2FSeamless/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharo-ide%2FSeamless/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pharo-ide%2FSeamless/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pharo-ide","download_url":"https://codeload.github.com/pharo-ide/Seamless/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219868429,"owners_count":16555761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["distributed-object","network","pharo","seamless"],"created_at":"2024-09-25T21:40:45.067Z","updated_at":"2025-10-23T02:31:23.991Z","avatar_url":"https://github.com/pharo-ide.png","language":"Smalltalk","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Seamless. Distributed object network.\n\n[![GitHub release](https://img.shields.io/github/release/pharo-ide/Seamless.svg)](https://github.com/pharo-ide/Seamless/releases/latest)\n[![Unit Tests](https://github.com/pharo-ide/Seamless/actions/workflows/tests.yml/badge.svg)](https://github.com/pharo-ide/Seamless/actions/workflows/tests.yml)\n\n[![Pharo 10](https://img.shields.io/badge/Pharo-10-informational)](https://pharo.org)\n\nFor details on Seamless design read [full documentation](https://github.com/SquareBracketAssociates/Booklet-Infrastructure).\n\n## Installation on client\nOn the client you can load default project group: \n```Smalltalk\nMetacello new\n  baseline: 'Seamless';\n  repository: 'github://pharo-ide/Seamless';\n  load\n```\nIt will include tests and tools to inspect remote objects.\n\nAnd use the following snippet for stable dependency in your client project baseline:\n```Smalltalk\nspec\n    baseline: 'Seamless'\n    with: [ spec repository: 'github://pharo-ide/Seamless' ]\n```\n## Installation on server\nYou can just use client instructions to prepare servers. But in case if you want to prepare really small images without any tools and even without SUnit then follow this section.\n\nOn server only Core group of project is needed:\n```Smalltalk\nMetacello new\n  baseline: 'Seamless';\n  repository: 'github://pharo-ide/Seamless';\n  load: #(Core)\n```\nIt will not include any tools to work with remote objects. And it will not install tests. If you want tests then add Tests group into a script.\n\nUse the following snippet for stable dependency in your project server baseline:\n```Smalltalk\nspec\n    baseline: 'Seamless'\n    with: [ spec \n        repository: 'github://pharo-ide/Seamless:v1.0.0';\n\tloads: #(Core)]\n```\n\n## How to use\nTo use Seamless SeamlessNetwork instance should be created on client and server:\n```Smalltalk\nnetwork := SeamlessNetwork new.\n```\nTo accept connections server should be started:\n```Smalltalk\nnetwork startServerOn: 40422.\n```\nClients could connect to server and retrieve remote environment:\n```Smalltalk\nremotePeer := network remotePeerAt: (TCPAddress ip: #[127 0 0 1] port: 40422).\nremoteSmalltalk := remotePeer remoteEnvironment.\n```\nOr use short version:\n```Smalltalk\nremoteSmalltalk := network environmentAt: (TCPAddress localAt: 40422)\n```\nremoteSmalltalk here is a proxy which delegates any received message to remote object. Remote messages are executed on the server which returns result back to the client. The result can be returned as another proxy or as a copy which contains other proxies.\n\nIn this example, the result is a reference to a remote Smalltalk instance. It can access globals from remote environment:\n```Smalltalk\nremoteTranscript := remoteSmalltalk at: #Transcript.\nremoteTranscript open; show: 'remote message'; cr\n```\nIt will open transcript on the server and print text on it.\n\nArguments of remote message are transferred to the server with the same logic as message result transferred to client. On server arguments can include proxies and server can send messages to them:\n```Smalltalk\nremoteTranscript print: #(1 2 3 4 5)\n```\nHere array will be passed to server as reference. Then on server transcript will interact with it to print it. And as result client will receive messages from the server.\n\nConcrete transfer strategy is depends on transferred object. It is specified in method #seamlessDefaultTransferStrategy:\n```Smalltalk\nObject\u003e\u003eseamlessDefaultTransferStrategy\n      ^SeamlessTransferStrategy defaultByReference\n\nNumber\u003e\u003eseamlessDefaultTransferStrategy\n      ^SeamlessTransferStrategy defaultByValue\n```\nDefault strategy could be overridden on network level:\n```Smalltalk\nnetwork transferByValue: (Instance of: Point).\nnetwork transferByReference: (Identical to: #specificSymbol)\n```\nIt allows us to tune network for specific application to optimize communication between distributed objects. There are few other transfer strategies which allow minimizing remote communication. Most interesting allows properties caching. It will transfer object reference together with specified properties. The following example will configure a network to transfer class reference together with a name:\n```Smalltalk\nnetwork transferByReference: (Kind to: Class) withCacheFor: #(name)\n```\nAnd then the proxy for the remote class will return #name from a local cache instead of real remote call.\n\n### Remote block execution\nSeamless allows evaluate a block of code on remote peers:\n```Smalltalk\nremotePeer evaluate: [1 + 2]. \"==\u003e3\"\n```\nGiven block is transferred to remote side and evaluated. A result is returned to the client. As in other cases, it could be a proxy or normal object.\n\nBlock can use globals. On the remote side, they will be local globals of this remote environment. The following example will show notification on remote image:\n```Smalltalk\nremotePeer evaluate: [Object inform: 'message from remote image'].\n```\nTemps and workspace variables can be used too. They will be transferred according to own strategies:\n```Smalltalk\n| result |\nresult := OrderedCollection new.\nremotePeer evaluate: [100 to: 500 do: [:i | result add: i factorial ]].\n```\nNon-local return is also supported in regular Smalltalk semantics:\n```Smalltalk\nremotePeer evaluate: [1 to: 10 do: [:i | i \u003e 5 ifTrue: [ ^i ]]]. \"==\u003e6\"\n```\nAlso, block can be evaluated asynchronously without waiting any result:\n```Smalltalk\n| result |\nresult := OrderedCollection new.\nremotePeer evaluateAsync: [result add: 1000 factorial]. \"it will not wait result\"\n```\n## Tools\nSeamless provides integration with GT tools. Remote proxies can be inspected to explore remote objects state with the ability to execute remote scripts (doIt, printIt). It is shown in [the demo about remote debugging](https://youtu.be/SgFjgQpo_nU) which is built with Seamless transport.\n\nTo analyze remote communication Seamless implements special tool SeamlessLogger. It is explained in the [documentation](https://ci.inria.fr/pharo-contribution/view/Books/job/PharoBookWorkInProgress/lastSuccessfulBuild/artifact/book-result/Seamless/Seamless.pdf). To activate logging evaluate:\n```Smalltalk\nSeamlessLogger startAFresh\n```\nTo disable:\n```Smalltalk\nSeamlessLogger stop\n```\nLogger prints all remote messages into Transcript. Also it provides profiler of remote communication. You can inspect request statistics using:\n```Smalltalk\nSeamlessLogger collectStatistics \"inspect it\"\n```\nStatistics shows s number of messages, receivers and bytes which was transferred over the network in a dimension of receiver class or message selector.\n\n## TODO\nIn the current version there are two missing features which will be supported in future:\n\n1) No garbage collection\n\nSeamlessNetwork keeps all objects which were transferred by reference. They will never be cleaned while the network is live. \nNow cleanup can be performed manually by evaluating \"network destroy\". It will clean all object caches and close all connections. It is not safe operation because removed objects can be still used by remote peers. Seamless tries to handle it properly with clear errors in such cases. \n\nIn future unused distributed objects will be cleaned automatically.\n\n2) No security: no authorization and encryption. Now for security purpose, you need external tools like VPN or SSH tunnel.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpharo-ide%2Fseamless","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpharo-ide%2Fseamless","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpharo-ide%2Fseamless/lists"}