Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LUAFDN-1706 Add support for devtools #84

Merged
merged 12 commits into from
Aug 22, 2023

Conversation

zovits
Copy link
Contributor

@zovits zovits commented Aug 22, 2023

(This PR also fixes up the CI since it was old and non-functional)

There is currently no proper way to log or profile Rodux store actions or performance. We need to provide insight into Rodux for our engineers to be able to write high quality Rodux usages.

This PR makes such a tool possible.

The fourth argument to Store.new takes a devtools object that you can optionally provide. A devtools object has only two requirements: devtools.__className must be "Devtools" and devtools:_hookIntoStore(store) must be a valid function call. Beyond that, your devtools can be anything you need it to be.

Devtools can be very useful during development in gathering performance data, providing introspection, debugging, etc. We leave the devtools implementation up to the user in order to support any and all use cases, such as store modification in unit testing, live state inspection plugins, and whatever else you come up with.

A simple example of a devtools that profiles and logs:

local Devtools = {}
Devtools.__className = "Devtools"
Devtools.__index = Devtools

-- Creates a new Devtools object
function Devtools.new()
	local self = setmetatable({
		_events = table.create(100),
		_eventsIndex = 0,
	}, Devtools)

	return self
end

-- Overwrites the store's reducer and flushHandler with wrapped versions that contain logging and profiling
function Devtools:_hookIntoStore(store)
	self._store = store
	self._source = store._source

	self._originalReducer = store._reducer
	store._reducer = function(state: any, action: any): any
		local startClock = os.clock()
		local result = self._originalReducer(state, action)
		local stopClock = os.clock()

		self:_addEvent("Reduce", {
			name = action.type or tostring(action),
			elapsedMs = (stopClock - startClock) * 1000,
			action = action,
			state = result,
		})
		return result
	end

	self._originalFlushHandler = store._flushHandler
	store._flushHandler = function(...)
		local startClock = os.clock()
		self._originalFlushHandler(...)
		local stopClock = os.clock()

		self:_addEvent("Flush", {
			name = "@@FLUSH",
			elapsedMs = (stopClock - startClock) * 1000,
			listeners = table.clone(store.changed._listeners),
		})
	end
end

-- Adds an event to the log
-- Automatically adds event.timestamp and event.source
function Devtools:_addEvent(eventType: "Reduce" | "Flush", props: { [any]: any })
	self._eventsIndex = (self._eventsIndex or 0) + 1
	self._events[self._eventsIndex] = {
		eventType = eventType,
		source = self._source,
		timestamp = DateTime.now().UnixTimestampMillis,
		props = props,
	}
end

-- Returns a shallow copy of the event log
function Devtools:GetLoggedEvents()
	return table.clone(self._events)
end

@zovits zovits self-assigned this Aug 22, 2023
Copy link
Contributor

@ZoteTheMighty ZoteTheMighty left a comment

Choose a reason for hiding this comment

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

Looks good so far. This should be easy to test, right?

Copy link
Contributor

@ZoteTheMighty ZoteTheMighty left a comment

Choose a reason for hiding this comment

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

Great work! Thanks for updating the CI :)

@zovits zovits merged commit 9099e95 into Roblox:master Aug 22, 2023
3 checks passed
@zovits zovits deleted the LUAFDN-1706/devtools-support branch August 22, 2023 23:00
zovits added a commit to zovits/rodux that referenced this pull request Aug 22, 2023
ZoteTheMighty added a commit that referenced this pull request Aug 22, 2023
* LUAFDN-1706 Add support for devtools (#84)

Co-authored-by: Paul Doyle <[email protected]>

* Bump version

* Don't add types

* Run CI on anything

* Add changelog

* Just run tests please

* Add test runners

---------

Co-authored-by: Zack Ovits <[email protected]>
Co-authored-by: zovits <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants