Skip to content

0.1.2

Latest

Choose a tag to compare

@hugithordarson hugithordarson released this 19 Sep 22:58
· 1 commit to master since this release

Interim development release. APIs are still being reshaped — the request/response model (ng.appserver.http) in particular — so expect incompatible changes between 0.1.x releases.

Page cache overhauled

  • restorePageFromCache/retainPageWithContextIDInCache/releaseLock replaced by an atomic checkout() returning an AutoCloseable NGPageLease (try-with-resources).
  • Thread-safety: synchronized cache maps, atomic contextID counter, and locking per page instance — requests for the same page serialize, different pages of one session run concurrently. A page returned as a response is rendered under its own lock.
  • Timed lock acquisition (10s default): contention surfaces as NGPageContendedException → 503 with Retry-After.
  • Partial-update entries reworked: flat parent chains, a per-page cap that only evicts superseded fragments (the newest entry per update container always survives), orphaned saves promoted rather than failing a completed action. Two session-lifetime memory leaks fixed.
  • Cache sizes and lock timeout constructor-injectable (defaults 100/50/10s). 30 new tests, including an application-free request-handler harness.

HTTP message model (redesign in progress)

  • Breaking: NGRequest/NGResponse/NGMessage are now interfaces (NGStandardRequest/NGStandardResponse implementing), live in the new ng.appserver.http package.
  • Breaking: responses are created through the new NGResponses factories instead of new NGResponse( content, status ). Note the argument order is now status-first — NGResponses.of( 404, "Not found" ) — with NGResponses.ok( content ) for the common case. The factories return the NGResponse interface; NGStandardResponse's constructors are protected.
  • NGRequest walking toward immutability: _setFormValues/_setCookieValues/setMethod deleted, settled fields final, remoteAddress a constructor argument (null = no transport peer), request content accepted as InputStream, httpVersion removed.
  • Session access belongs to the context: NGContext.session()/existingSession()/hasSession() are the supported API; the NGRequest equivalents are deprecated. Also deprecated, scheduled for deletion: NGRequest._setContext() (renamed from setContext) and uploadedFiles().
  • Breaking: NGCookie is now an immutable record. name/value are required, SameSite is an enum, maxAge given as a Duration (null = session cookie, Duration.ZERO = delete, negative rejected), secure/httpOnly accessors lose their is-prefix. Only Max-Age is emitted, never Expires.
  • NGAdaptorRaw and NGAdaptorPlain deleted, we'll only be targeting Jetty while developing.

Templating & elements

  • Attribute values in generated element tags are now escaped
  • Tag names are declared in parsley-tag-aliases.properties — a single source of truth read by both the runtime and the Parsley template editor. Every such file on the classpath is loaded (first declaration wins, conflicts warned); explicit code registrations still override.
  • .apiext definitions ship for all 26 framework elements — bindings with direction and types, required flags, defaults, deprecations, cross-binding constraints.
  • NGSwitchComponent: fixed an elementID-minting race that could permanently merge two cases' component caches.
  • NGRepetition: fixed infinite recursion in takeValuesFromRequest for count-bound repetitions.
  • NGPopUpButton: the selection binding is the sole authority for rendered selection when bound; out-of-range selection indexes fail deliberately.
  • NGTextField: (temporarily) doesn't attempt to format a null value.

Security

  • Session cookie hardened by default: HttpOnly, SameSite=Lax, Path=/, host-only. Secure remains a deployment decision; createSessionCookie is protected and overridable.
  • /ng/dev/eval stays loopback-restricted and rejects form-encoded bodies with a clear error.

Developer tooling

  • New endpoints /ng/dev/eval and /ng/dev/problems; Parslips dev-server support (apps self-register, reporting runtime=ng); pid logged at startup.
  • Dev tools moved out of ng.appserver.privates: NGConsoleCapture → ng-core's ng.dev; the rest → new ng.appserver.dev.

Infrastructure & dependencies

  • NGLifebeatThread uses Java's HttpClient instead of raw sockets.
  • Jetty 12.1.8 → 12.1.13, JUnit 6.0.3 → 6.1.3, slf4j 2.0.17 → 2.0.19, vermilingua 1.1.3 → 1.1.10; Maven plugins refreshed.

Full Changelog: v0.1.1...v0.1.2