Skip to content

Support incubator features preview in zilla release docker image#753

Merged
jfallows merged 4 commits into
aklivity:developfrom
akrambek:feature/670
Jan 23, 2024
Merged

Support incubator features preview in zilla release docker image#753
jfallows merged 4 commits into
aklivity:developfrom
akrambek:feature/670

Conversation

@akrambek

@akrambek akrambek commented Jan 20, 2024

Copy link
Copy Markdown
Contributor

Description

Support incubator features preview in zilla release docker image.

Fixes #670

Comment on lines +30 to +35

@Override
public String name()
{
return null;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be removed, agree?

<version>1.1.0.7</version>
<license>The Apache License, Version 2.0</license>
</artifact>
</license-lookup>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this file, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was half through and hasn't done cleanup just wanted to get your initial feedback with design first.

}

return construct.apply(unmodifiableMap(factoriesByName));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that some services (like commands) don't have names to store in a map, I think this instantiate method goes back to FactorySpi, but without the check for incubator.

Instead, I think we want to simplify to create a filtered Iterable<S> since that's at the core of what we're trying to do with @Incubating annotation.

package io.aklivity.zilla.runtime.common.feature;

public final class FeatureLoader
{
    public static final boolean INCUBATOR_ENABLED = incubatorEnabled();
    public static final Predicate<Object> FEATURE_ENABLED = FeatureLoader::featureEnabled;

    public static <S> Iterable<S> load(Class<S> service)
    {
        Iterable<S> loader = ServiceLoader.load(service);
        return StreamSupport.stream(loader.spliterator(), false)
            .filter(FEATURE_ENABLED)::iterator;
    }

    private static boolean featureEnabled(
        Object feature)
    {
        return INCUBATOR_ENABLED || !feature.getClass().isAnnotationPresent(Incubating.class);
    }

    private static boolean incubatorEnabled()
    {
        final Module module = Feature.class.getModule();
        final String override = System.getProperty("zilla.incubator.enabled");

        return override != null
            ? Boolean.parseBoolean(override)
            : module == null ||
            "develop-SNAPSHOT".equals(module
                .getDescriptor()
                .version()
                .map(ModuleDescriptor.Version::toString)
                .orElse("develop-SNAPSHOT"));
    }
}

Then use FeatureLoader.load(...) instead of ServiceLoader.load(...) for both engine and command.

public interface FeatureSpi
{
String name();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't need this class if we use FeatureLoader approach instead.

* License for the specific language governing permissions and limitations
* under the License.
*/
package io.aklivity.zilla.runtime.common.annotation;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest we move this alongside FeatureLoader in io.aklivity.zilla.runtime.common.feature package.

Comment on lines +20 to +22
exports io.aklivity.zilla.runtime.common;

uses io.aklivity.zilla.runtime.common.CommonSpi;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will change with the repackaging.


assertEquals(1, status);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need ZillaMain tests in common? Seems like the dependency is inverted.

Comment on lines +61 to +65
if (!service.getClass().getPackageName().contains("incubator") ||
incubatorEnabled)
{
service.mixin(builder);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use FeatureLoader.load(...) instead, so no need for if condition around service.mixin(...) call.

@akrambek akrambek marked this pull request as ready for review January 22, 2024 23:03
import java.util.function.Predicate;
import java.util.stream.StreamSupport;

public final class FeatureLoader

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to FeatureFilter?

Comment on lines +28 to +29
public static final boolean INCUBATOR_ENABLED = incubatorEnabled();
public static final Predicate<Object> FEATURE_ENABLED = FeatureLoader::featureEnabled;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public static final boolean INCUBATOR_ENABLED = incubatorEnabled();
public static final Predicate<Object> FEATURE_ENABLED = FeatureLoader::featureEnabled;
private static final boolean INCUBATOR_ENABLED = incubatorEnabled();
private static final Predicate<Object> FEATURE_ENABLED = FeatureLoader::featureEnabled;

Iterable<S> factories,
Function<Map<String, S>, F> construct)
{
Map<String, S> factoriesByName = new TreeMap<>();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

factoriesByType ?

Function<Map<String, S>, F> construct)
{
Map<String, S> factoriesByName = new TreeMap<>();
for (S factory : factories)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommend we apply the filter(...) call here around factories instead of in each subclass.

@jfallows jfallows merged commit 5371f82 into aklivity:develop Jan 23, 2024
@akrambek akrambek deleted the feature/670 branch January 23, 2024 01:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support incubator features preview in zilla release docker image

2 participants