All Projects → adambrewster → Defer.jl

adambrewster / Defer.jl

Licence: MIT license
Simplified resource cleanup for julia.

Programming Languages

julia
2034 projects

Projects that are alternatives of or similar to Defer.jl

Win10clean
Cleanup your Windows 10 environment
Stars: ✭ 187 (+790.48%)
Mutual labels:  cleanup
mail-deduplicate
📧 CLI to deduplicate mails from mail boxes.
Stars: ✭ 134 (+538.1%)
Mutual labels:  cleanup
puppet-ghostbuster
👻 Dead code detector for Puppet
Stars: ✭ 83 (+295.24%)
Mutual labels:  cleanup
Fengniao
A command line tool for cleaning unused resources in Xcode.
Stars: ✭ 2,852 (+13480.95%)
Mutual labels:  cleanup
gbp
Golang Best Practices (GBP™)
Stars: ✭ 25 (+19.05%)
Mutual labels:  defer
ILStrip
C# Assembly unused classes/references/resources cleaner
Stars: ✭ 20 (-4.76%)
Mutual labels:  cleanup
Chemo
Remove pre-installed junk from Windows 10.
Stars: ✭ 144 (+585.71%)
Mutual labels:  cleanup
ncdu-diff
ncdu fork that can compare and diff results
Stars: ✭ 21 (+0%)
Mutual labels:  cleanup
cleanup
Remove gone Git branches with ease.
Stars: ✭ 21 (+0%)
Mutual labels:  cleanup
silly-android
Android plugins for Java, making core Android APIs easy to use
Stars: ✭ 40 (+90.48%)
Mutual labels:  cleanup
PowerSponse
PowerSponse is a PowerShell module focused on targeted containment and remediation during incident response.
Stars: ✭ 35 (+66.67%)
Mutual labels:  cleanup
cleanup
This tool was built for me and you to help us `cleanup` our folders with just a single command from the terminal.
Stars: ✭ 29 (+38.1%)
Mutual labels:  cleanup
SteroidsDI
Advanced Dependency Injection to use every day.
Stars: ✭ 15 (-28.57%)
Mutual labels:  defer
Privacy.sexy
Open-source tool to enforce privacy & security best-practices on Windows and macOS, because privacy is sexy 🍑🍆
Stars: ✭ 221 (+952.38%)
Mutual labels:  cleanup
beekeeper
Service for automatically managing and cleaning up unreferenced data
Stars: ✭ 43 (+104.76%)
Mutual labels:  cleanup
Assetchecker
👮Sanitize your Assets.xcassets files
Stars: ✭ 167 (+695.24%)
Mutual labels:  cleanup
project-curator
A convenient tool to help cleaning and to maintain Unity Projects ✨
Stars: ✭ 99 (+371.43%)
Mutual labels:  cleanup
drone-cleanup
Clean up completed drone.io jobs and pods from the Kubernetes cluster
Stars: ✭ 25 (+19.05%)
Mutual labels:  cleanup
jetbrains-utility
Remove/Backup – settings & cli for macOS (OS X) – DataGrip, AppCode, CLion, Gogland, IntelliJ, PhpStorm, PyCharm, Rider, RubyMine, WebStorm
Stars: ✭ 62 (+195.24%)
Mutual labels:  cleanup
pysorter
A command line utility for organizing files and directories according to regex patterns.
Stars: ✭ 40 (+90.48%)
Mutual labels:  cleanup

Defer.jl

Defer.jl provides simplified resource cleanup in julia. When julia programs interface with external resources (often wrapping external libraries), they must often arrange for those resources to be freed, closed, cleaned up, or otherwise disposed of after use. This package provides a golang inspired @defer macro to make it easier for users to free resources at the correct time.

This package is meant as a pathfinder for an eventual language feature that will take its place. In the meantime, it's usable in its current form. By adopting this convention now you will be ready for the future and also help shape the language by determining which forms are most useful and which corner cases cause friction.

Basic Usage

The most basic usage is to create a scope and execute code within it. Within a scope you can schedule code for execution when the scope terminates.

@scope begin
    @defer println("world")
    println("hello")
end

prints

hello
world

@! is a shortcut for deferring a call to close.

type A
    a::String
end
Base.close(a::A) = println("Closing $a")
use(a::A) = println("Using $a")
@scope begin
    a = @! A("a")
    use(a)
end

prints

Using A("a")
Closing A("a")

Module Development

Module authors should use defer to schedule cleanup of resources allocated in the __init__() function. (A global top-level scope is always exists.) The user may execute all pending defered actions by calling pop_scope!(1). The module can then be reinitialized by the user calling __init__().

Modules should not use defer (or finalizer) to schedule cleanup of resources allocated by the user. Instead, add a method to Base.close, so that your user may schedule cleanup of the resource easily by adding @! where your constructor is called.

module Example
include("libfoo.jl")

# Some global context that our library uses
const foo_context = Ref{fooContext_t}(C_NULL)

# Initialize the library when the module is (re-)loaded
function __init__()
  fooCreateContext(foo_context)
  # don't use atexit, defer the action instead
  @defer fooDestroyContext(foo_context[])
end

# An object in the library that will be made available to julia users
immutable Foo
  ptr::fooThing_t
end

# Create the object in the wrapper constructor
function Foo(x...)
  thing = Ref{fooThing_t}
  fooCreateThing(foo_context[], thing, x...)
  # don't schedule thing to be destroyed!
  Foo(thing[])
end

# Extend the close function so the user can call @! Foo(...) to create an object and control when it will be destroyed.
Base.close(foo::Foo) = fooDestroyThing(foo_context[], foo.ptr)
end

More Usage

Sometimes scope() do ... end is inconvenient, so there's also a @scope macro.

function f()
    a = @! A("a")
    use(a)
end
@scope f()

is equivalent to the above.

When applied to a method definition, @scope wraps the body in a scope.

@scope g() = use(@! A("a"))
g()

is also equivalent.

@scope can also be applied to a let statement to wrap the statement in a scope and automatically schedule all of the leted variables to be closed.

@scope let f = open("/dev/null", "w")
  println(f, "Hello, nobody!")
end

Exceptions from the scope or its deferred actions propagate to the caller. If there are multiple exceptions, they're wrapped in a CompositeException.

try
    scope() do
        @defer throw("Deferred exception")
        throw("Exception")
    end
catch e
    @show e
    nothing
end

prints

e = CompositeException(Any["Exception","Deferred exception"])

Future Work

This package is offered as an example of how deferred resource clean-up may work in julia. Package authors may experiment to see if the feature is useful, and the maintainers of the language may follow its example and lessons learned in implementing a similar feature in julia.

Additional work and questions to be resolved to adopt such a feature include the following:

  • Which function should be used to dispose of resources? I chose to use close for this purpose because it already exists in Base and any other extension of the function is unlikely to conflict with this usage. Extending finalize interferes with that function's usage to call any finalizers scheduled on the object. Other options (e.g. dispose, destroy, cleanup, etc) may be suitable but are commonly used in other packages so that their use in this package would conflict, but the community could adopt one such function, and export it from Base.

  • When should deferred actions be executed? This package requires the user to specify when deferred actions are to be run by declaring scopes. A built-in language feature would likely adopt a rule such as at the end of the currently executing function or let-block. In particular, deferred actions should not be executed when lines from the REPL of IJulia cells terminate or when a module is initialized.

  • Should module initialization be a special case? I have suggested the __init__ function always be run a scope which will exist for life of the module. Alternately, there could be a corresponding __uninit__ function which could be used to similar effect.

  • Should a package author schedule for destruction resources which will be returned to the user? The current practice of scheduling resources for destruction in their constructor (e.g. by calling finalizer or similar) is convenient when called directly from the REPL as the user can usually not worry about resource clean-up. For performance sensitive code, however, the option to handle resource cleanup manually may be necessary. It would be useful for the community to adopt a single convention for package authors to follow in addressing these two competing desires.

Disclaimer.

DISTRIBUTION STATEMENT A. Approved for public release: distribution unlimited.

© 2017 MASSACHUSETTS INSTITUTE OF TECHNOLOGY.

  • Subject to FAR 52.227-11 – Patent Rights – Ownership by the Contractor (May 2014).
  • SPDX-License-Identifier: MIT.

This material is based upon work supported by the Undersecretary of Defense for Research and Engineering under Air Force Contract No. FA8721-05-C-0002. Any opinions, findings, conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of USD(R&E).

The software/firmware is provided to you on an As-Is basis.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].